[Android Exercise]仿微信遊戲界面PART.1—ConstraintLayout和RecyclerView的應用

前幾天打開了微信遊戲,找到了裏面有一部分內容非常適合用來做ConstraintLayout和RecyclerView的練習,然而前幾天一直在家或者摸魚,加上標註什麼的一直拖到了今天,那麼現在就來練練手。

*******************************************

讓我們來看看我截出來需要被實現的部分:




1、分析模塊

將每一個部分都做成一個子項,使用RecyclerView實現,其實和普通的RecyclerView一樣,只是將子項佈局改成了ConstraintLayout(我感覺這裏使用ConstraintLayout比使用RelativeLayout更方便一些)。下面是我對這個佈局內容的一些劃分:



紅色的線是輔助線,我用來完成佈局的對齊(在這裏其實感覺用不用都可以,但是GuideLine不得不說確實是個好東西)。綠色框內則是一個部分子佈局需要被隱藏的部分,因此決定將整個綠色框內寫在一個RelativeLayout之中。


2、實現

首先別忘了導入RecyclerView依賴庫!導入的方法之前有記錄過,可以在app的build.gradle中手打或者使用Project Structure添加。

步驟依舊是從需要被展現的信息開始。一個子項中被展現出來的內容如下:



但我們有的信息是可以自動生成的,如序號,綠框內的信息(模板語句是一樣的)。因此新建Game類,新建字段gameName和gameDesc,添加構造函數和返回函數(其實字段中也需要有gamePic,但是我懶得找圖片了,就沒有加進去)

public class Game {
    private String gameName;
    private String gameDesc;

    public Game(String gameName, String gameDesc){
        this.gameName = gameName;
        this.gameDesc = gameDesc;
    }

    public String getGameName(){
        return gameName;
    }

    public String getGameDesc(){
        return gameDesc;
    }
}

之後就要寫子項佈局了。新建game_item.xml,這裏我用的是ConstraintLayout:

設立兩條輔助線GuideLine,分別是距離12dp和38dp的劃分,就是上上圖中的兩條打豎的橫線,用來對齊子項內的部分元素。

<android.support.constraint.Guideline
        android:id="@+id/twelveDpGuideLine"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:orientation="vertical"
        app:layout_constraintGuide_begin="12dp"/>

    <android.support.constraint.Guideline
        android:id="@+id/thirdtyEightDPGuideLine"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:orientation="vertical"
        app:layout_constraintGuide_begin="38dp" />

先用序號部分作爲一個示例開始寫吧。序號部分的數字是父佈局左側和38dp輔助線水平居中的,這是我的TextView:

<TextView
        android:id="@+id/textNum"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="23sp"
        android:textColor="#999"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="@id/thirdtyEightDPGuideLine"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="20dp"/>


其他的TextView和ImageView和Button基本同理,設置約束和margin等。

※對已經確定大小(寬高不是0dp)的控件進行左右相對約束則可以讓它水平居中(豎直居中同理)

※如果margin不起作用,請先確定是否有對margin的那個方向進行約束。可以回看ConstraintLayout使用方法和注意點那篇博文。


單獨分開綠色框那一部分,是因爲裏面的內容都是可能被一起隱藏掉的。這裏我用RelativeLayout包含裏面的內容,包括兩個TextView和一個分割線(View):

<RelativeLayout
        android:id="@+id/textDetails"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/imgGamePic"
        app:layout_constraintLeft_toRightOf="@id/thirdtyEightDPGuideLine"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginTop="9dp">

        <TextView
            android:id="@+id/textDetail1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textColor="#999"
            android:textSize="12sp"
            android:layout_marginLeft="9dp"/>

        <TextView
            android:id="@+id/textDetail2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/textDetail1"
            android:textColor="#999"
            android:textSize="12sp"
            android:layout_marginTop="2dp"
            android:layout_alignLeft="@id/textDetail1"/>

        <View
            android:layout_width="2dp"
            android:layout_height="30dp"
            android:background="#f1f1f1"/>

    </RelativeLayout>


最後在底部加一條分界線,用來分來每個子項:


<View
        android:layout_width="0dp"
        android:layout_height="1dp"
        android:background="#dfdfdf"
        app:layout_constraintLeft_toLeftOf="@id/twelveDpGuideLine"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/textDetails"
        app:layout_goneMarginTop="14dp"
        android:layout_marginTop="14dp"/>


爲什麼我覺得在這個item之中ConstraintLayout比RelativeLayout好用呢。由於我們的分界線的marginTop是相對於綠色框的RelativeLayout的內容,然而當我們隱藏了RelativeLayout後,View將會直接對齊RelativeLayout原來對齊的內容,也就是我上面對齊的gamePic。爲了解決這個問題,ConstraintLayout中有一個goneMargin屬性,它在約束控件隱藏的情況下被啓用,效果相當於margin。(但不知道爲什麼我這裏取消了goneMargin後,效果仍不變,也就是marginTop依舊存在,求解答)


這是我取消了marginTop之後不使用goneMarginTop和使用goneMarginTop的結果:



可以看出,goneMargin屬性確實只在被約束對象被隱藏後才啓用的。


那麼到這裏,子項佈局就完成了。接下來RecyclerView就和之前的步驟基本一樣。但因爲這裏除了前三項的綠色框內容(RelativeLayout)不需要被隱藏,三項以後的內容都不予顯示,因此在GameAdapter中的onBindViewHolder中加入判斷語句:

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Game game = gameList.get(position);
        holder.gameNum.setText(String.valueOf(position+1));
        holder.gameName.setText(game.getGameName());
        holder.gameDesc.setText(game.getGameDesc());
        if (position>2){
            holder.gameDetails.setVisibility(View.GONE);
        }else{
            holder.gameDetail1.setText("最近超過"+ (new Random().nextInt(8)+1) + "百萬人在玩");
            holder.gameDetail2.setText((new Random().nextInt(8)+1) +"萬人剛加入這款遊戲");
        }
    }

※ position是int類型的,而TextView接受的數據類型是CharSequence類型,因此一定要使用數據轉換將int轉換爲String,否則編譯將會報錯:android.content.res.Resources$NotFoundException: String resource ID #0x0


完成了所有工作之後,來看看整體佈局效果(這裏的圖片因爲我懶得找了,就直接用背景色代替了):



初步完成!





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章