Android编程思想,面向对象程序设计第六篇——封装(上)布局模块化

时间:2022-10-11 10:55:55

上一节我们讲了继承,这一节我们开始讲封装。为什么要封装呢?封装是对代码信息和功能的归类,以方便于查找、调用、修改、

拓展、代码复用,提高可读性。没有经过封装的代码往往需要一句一句的看才知道是什么意思,使用和拓展起来很费劲而且基本很难复用。

下面我们就用一个布局封装的列子来感受一下:比如说这个红色方框内的布局

Android编程思想,面向对象程序设计第六篇——封装(上)布局模块化

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/game_item_layout_has_star_game_item"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:descendantFocusability="blocksDescendants"
    android:paddingLeft="15dp"
    android:paddingRight="15dp">

        <!-- 左边 -->
        <ImageView
            android:id="@+id/game_item_layout_has_star_game_icon"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_alignParentLeft="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="15dp"
            android:scaleType="centerCrop" />
        <!-- 右边 -->
        <com.view.DownloadProgressButton
            android:id="@+id/game_item_layout_has_star_roundProgressBar"
            style="@style/Progress_horizontal"
            android:layout_width="55dp"
            android:layout_height="25dp"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_gravity="center"
            android:focusable="false"
            app:DownloadProgressButton_cornerRadius="25dp"
            app:DownloadProgressButton_maxHeight="25dp"
            app:DownloadProgressButton_textSize="13sp" />
        <!-- 中间 -->
        <LinearLayout
            android:id="@+id/game_item_layout_has_star_ll_content"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_gravity="center_vertical"
            android:layout_toLeftOf="@id/game_item_layout_has_star_roundProgressBar"
            android:layout_toRightOf="@id/game_item_layout_has_star_game_icon"
            android:background="@android:color/transparent"
            android:orientation="vertical"
            android:paddingBottom="15dp"
            android:paddingRight="10dp"
            android:paddingTop="15dp">

            <TextView
                android:id="@+id/game_item_layout_has_star_game_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="3.5dp"
                android:ellipsize="marquee"
                android:focusable="true"
                android:focusableInTouchMode="true"
                android:marqueeRepeatLimit="marquee_forever"
                android:singleLine="true"
                android:textColor="@color/black333"
                android:textSize="15sp" />

            <TextView
                android:id="@+id/game_item_layout_has_star_game_info"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:ellipsize="marquee"
                android:singleLine="true"
                android:textColor="@color/huise999999"
                android:textSize="13sp" />

            <RatingBar
                android:id="@+id/game_item_layout_has_star_room_ratingbar"
                style="@style/smallRatingBar"
                android:layout_width="wrap_content"
                android:layout_height="11dp"
                android:layout_marginTop="3.5dp"
                android:numStars="5"
                android:rating="2.5"
                android:stepSize="0.5" />
        </LinearLayout>


        <View
            android:id="@+id/game_item_layout_has_star_line"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_alignLeft="@+id/game_item_layout_has_star_ll_content"
            android:layout_alignParentBottom="true"
            android:background="@color/light_gray" />

</RelativeLayout>


每次在使用到这个布局的时候都要写下面一串代码,好烦
                mIconImage        = (ImageView)view.findViewById(R.id.game_item_layout_has_star_game_icon);
mNameText         = (TextView) view.findViewById(R.id.game_item_layout_has_star_game_title);
mRatingBar       = (RatingBar) view.findViewById(R.id.game_item_layout_has_star_room_ratingbar);
mInfoText         = (TextView)view.findViewById(R.id.game_item_layout_has_star_game_info);
mDownloadButton   = (DownloadProgressButton)view.findViewById(R.id.game_item_layout_has_star_roundProgressBar);
mDownloadButton.setBgColor(this.getResources().getColor(R.color.download_button_bg));
mDownloadButton.setProgressColor(this.getResources().getColor(R.color.download_progress_color));
mDownloadButton.setOpenTextColor(this.getResources().getColor(R.color.title_color));
mDownloadButton.setIdleTextColor(this.getResources().getColor(R.color.white));
mLine    = findViewById(R.id.game_item_layout_has_star_line);
GlideImageLoadUtils.displayImage(getContext(),bean.getGameIconUrl(), mIconImage, GlideImageLoadUtils.getGameIconOptions());
mNameText.setText(bean.getGameName());
mRatingBar.setRating((float)bean.gameStar);
mInfoText.setText(bean.getGameDownloadNum() + "下载  " + CommonHelper.formatSize(bean.gameSize));
mDownloadButton.setDownloadInfo(bean, from);

setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
ActivityUtils.startNormalGameDetailActivity(mContext,bean, "");


}
});

而且要是这个时候要在这个布局上面多加一个TextView,比如说用来显示游戏的类型。如果有很多界面都用到这个布局的话,
你得一个界面一个界面的查找,修改。这样不仅效率低,容易改错,还很影响心情。

               但是,如果你懂得封装起来的话,就简单多了


public class GameItemLayoutHasStarextends RelativeLayout {

private ImageView              mIconImage;
private RatingBar              mRatingBar;
private TextView               mNameText;
private TextView               mInfoText;
private DownloadProgressButton mDownloadButton;
private View                   mLine;

public GameItemLayoutHasStar(Context context, AttributeSet attrs) {
super(context, attrs);
}


@Override
protected void onFinishInflate() {
super.onFinishInflate();
initView(this);
}

private void initView(View view){//初始化
mIconImage        = (ImageView)view.findViewById(R.id.game_item_layout_has_star_game_icon);
mNameText         = (TextView) view.findViewById(R.id.game_item_layout_has_star_game_title);
mRatingBar       = (RatingBar) view.findViewById(R.id.game_item_layout_has_star_room_ratingbar);
mInfoText         = (TextView)view.findViewById(R.id.game_item_layout_has_star_game_info);
mDownloadButton   = (DownloadProgressButton)view.findViewById(R.id.game_item_layout_has_star_roundProgressBar);
mDownloadButton.setBgColor(this.getResources().getColor(R.color.download_button_bg));
mDownloadButton.setProgressColor(this.getResources().getColor(R.color.download_progress_color));
mDownloadButton.setOpenTextColor(this.getResources().getColor(R.color.title_color));
mDownloadButton.setIdleTextColor(this.getResources().getColor(R.color.white));
mLine    = findViewById(R.id.game_item_layout_has_star_line);
}
//需要设置背景的再设置避免重复设置背景过度绘制,如榜单的item 就已经有设置了背景在此布局就不需要再设置了
public void setmBackGround(){
this.setBackgroundResource(R.drawable.selector_white_btn_bg);
}

public void setLineVisiable(int visiable){
mLine.setVisibility(visiable);
}
public void setGameInfoBean(final GameListBean bean, int from){//设置数据
GlideImageLoadUtils.displayImage(getContext(),bean.getGameIconUrl(), mIconImage, GlideImageLoadUtils.getGameIconOptions());
mNameText.setText(bean.getGameName());
mRatingBar.setRating((float)bean.gameStar);
mInfoText.setText(bean.getGameDownloadNum() + "下载  " + CommonHelper.formatSize(bean.gameSize));
mDownloadButton.setDownloadInfo(bean, from);

setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
ActivityUtils.startNormalGameDetailActivity(mContext,bean, "");

}
});
}
}

<?xml version="1.0" encoding="utf-8"?>
<GameItemLayoutHasStar

xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/game_item_layout_has_star_game_item"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:descendantFocusability="blocksDescendants"
    android:paddingLeft="15dp"
    android:paddingRight="15dp">

        <!-- 左边 -->
        <ImageView
            android:id="@+id/game_item_layout_has_star_game_icon"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:layout_alignParentLeft="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="15dp"
            android:scaleType="centerCrop" />
        <!-- 右边 -->
        <com.view.DownloadProgressButton
            android:id="@+id/game_item_layout_has_star_roundProgressBar"
            style="@style/Progress_horizontal"
            android:layout_width="55dp"
            android:layout_height="25dp"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_gravity="center"
            android:focusable="false"
            app:DownloadProgressButton_cornerRadius="25dp"
            app:DownloadProgressButton_maxHeight="25dp"
            app:DownloadProgressButton_textSize="13sp" />
        <!-- 中间 -->
        <LinearLayout
            android:id="@+id/game_item_layout_has_star_ll_content"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_gravity="center_vertical"
            android:layout_toLeftOf="@id/game_item_layout_has_star_roundProgressBar"
            android:layout_toRightOf="@id/game_item_layout_has_star_game_icon"
            android:background="@android:color/transparent"
            android:orientation="vertical"
            android:paddingBottom="15dp"
            android:paddingRight="10dp"
            android:paddingTop="15dp">

            <TextView
                android:id="@+id/game_item_layout_has_star_game_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="3.5dp"
                android:ellipsize="marquee"
                android:focusable="true"
                android:focusableInTouchMode="true"
                android:marqueeRepeatLimit="marquee_forever"
                android:singleLine="true"
                android:textColor="@color/black333"
                android:textSize="15sp" />

            <TextView
                android:id="@+id/game_item_layout_has_star_game_info"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:ellipsize="marquee"
                android:singleLine="true"
                android:textColor="@color/huise999999"
                android:textSize="13sp" />

            <RatingBar
                android:id="@+id/game_item_layout_has_star_room_ratingbar"
                style="@style/smallRatingBar"
                android:layout_width="wrap_content"
                android:layout_height="11dp"
                android:layout_marginTop="3.5dp"
                android:numStars="5"
                android:rating="2.5"
                android:stepSize="0.5" />
        </LinearLayout>


        <View
            android:id="@+id/game_item_layout_has_star_line"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_alignLeft="@+id/game_item_layout_has_star_ll_content"
            android:layout_alignParentBottom="true"
            android:background="@color/light_gray" />

</GameItemLayoutHasStar>

//把布局的获取控件和设置数据方法封装起来,在布局里面使用这个自定义的类就可以了。

在使用到该布局的地方调用
GameItemLayoutHasStar gameItemLayout = (GameItemLayoutHasStar)LayoutInflater.
from(mContext).inflate( R.layout.game_item_layout_has_star, parent,false);
gameItemLayout.setGameInfoBean(gameListBean ,from);
就可以了。在遇到需要修改的时候只需要修改布局文件和GameItemLayoutHasStar类就可以了,
不需要再去修改那么多个地方的代码。