1. 程式人生 > >Android簡單實現仿支付寶新年紅包活動頁面的動態佈局效果

Android簡單實現仿支付寶新年紅包活動頁面的動態佈局效果

大家好,隔了很長一段時間沒有更新部落格了,有幾方面的原因,一是因為年底了在準備換工作的事情,二是因為年底了公司專案需要一個歸檔和總結的內容,所以做了一個月的開發共通元件的抽取成SDK的工作,內容都是一些平時比較常用的功能模組,比如像登入註冊,第三方註冊和分享,視訊播放等程式碼,已經抽取成了單獨的類庫,工程關聯就可以根據開發文件呼叫使用了,從一定的角度上來說為以後的專案節約了一定的時間和人力投入,如果大家有需要的話可以留言,後續會寫一寫這些模組的實現與使用,以及大家如果有哪些方面的問題或者功能無法實現的,可以在文章下方留言,大家一起探討,有時間的話我會盡量給大家寫一個Demo,共同進步嘛,雖然我比不上那些大牛,但是我相信自己堅持下去,一定是會有成為大牛的一天的,我們大家都是!

好了,廢話不多說了,正式進入今天的主題,這件事發生在前不久,是我的一個朋友問我的一個問題,她(是個美女~)在開發中遇到了一個問題,就是類似支付寶的新年活動版塊的效果,如下圖所示:
這裡寫圖片描述

她們也要做一個類似的活動廣告效果,支付寶的介面肯定是新年過完後中間的“新春送福”模組就消失了,後面的模組動態的往前補齊,所以這個功能肯定是根據從伺服器獲取的某個欄位來判斷的,而不是寫死的佈局,要不然使用者體驗就特別差了,我暫時把這個欄位設想為boolean值,true代表新年,顯示“新春祝福”模組,false代表非新年時間段,顯示日常模組,這樣就能很靈活的控制介面展示效果了,剛開始她給我截圖的時候我也犯難了,這可怎麼做呢,她之前的工程結構是用的GridView,我想用GridView的話那怎麼能插進去的,然後也百度找了找,沒有找到相關的資源,後來乾脆就自己寫一個吧,想了好幾種方法,都被自己給否定掉了,後來一想,嗯,只能根據boolean值來載入兩套佈局了,意思就是從上到下是一個LinearLayout,然後一排一排的addView(view)方式來做出這個效果了,嗯,想到了就開始做吧,程式碼陸續如下~~~

首先新建兩套佈局檔案,分別命名為item_normal.xml和item_party.xml,程式碼很簡單,示範用就寫的是個意思咯

  • item_normal.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation
="horizontal" >
<RelativeLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:layout_weight="1" > <ImageView android:id="@+id/image1" android:layout_width="50dp" android:layout_height="50dp" android:layout_centerHorizontal="true" /> <TextView android:id="@+id/text1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/image1" android:layout_centerHorizontal="true" android:layout_marginTop="3dp" android:textColor="#000000" android:textSize="15sp" /> </RelativeLayout> <RelativeLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:layout_weight="1" > <ImageView android:id="@+id/image2" android:layout_width="50dp" android:layout_height="50dp" android:layout_centerHorizontal="true" /> <TextView android:id="@+id/text2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/image2" android:layout_centerHorizontal="true" android:layout_marginTop="3dp" android:textColor="#000000" android:textSize="15sp" /> </RelativeLayout> <RelativeLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:layout_weight="1" > <ImageView android:id="@+id/image3" android:layout_width="50dp" android:layout_height="50dp" android:layout_centerHorizontal="true" /> <TextView android:id="@+id/text3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/image3" android:layout_centerHorizontal="true" android:layout_marginTop="3dp" android:textColor="#000000" android:textSize="15sp" /> </RelativeLayout> <RelativeLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:layout_weight="1" > <ImageView android:id="@+id/image4" android:layout_width="50dp" android:layout_height="50dp" android:layout_centerHorizontal="true" /> <TextView android:id="@+id/text4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/image4" android:layout_centerHorizontal="true" android:layout_marginTop="3dp" android:textColor="#000000" android:textSize="15sp" /> </RelativeLayout> </LinearLayout>
  • item_party.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <RelativeLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:layout_weight="1" >

        <ImageView
            android:id="@+id/item_image1"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_centerHorizontal="true"
            android:src="@drawable/ic_launcher" />

        <TextView
            android:id="@+id/item_text1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/item_image1"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="3dp"
            android:text="債權轉讓"
            android:textColor="#000000"
            android:textSize="15sp" />
    </RelativeLayout>

    <RelativeLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:layout_weight="2" >

        <ImageView
            android:id="@+id/item_image2"
            android:layout_width="match_parent"
            android:layout_height="68dp"
            android:layout_centerHorizontal="true"
            android:scaleType="centerCrop"
            android:src="@drawable/icon1" />
    </RelativeLayout>

    <RelativeLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:layout_weight="1" >

        <ImageView
            android:id="@+id/item_image3"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_centerHorizontal="true"
            android:src="@drawable/ic_launcher" />

        <TextView
            android:id="@+id/item_text3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/item_image3"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="3dp"
            android:text="債權轉讓"
            android:textColor="#000000"
            android:textSize="15sp" />
    </RelativeLayout>

</LinearLayout>

好了,佈局檔案寫好了,下面主要就是控制邏輯部分了,本來圖片和文字這兩部分都應該是從伺服器中獲取用來填充,這個案例只是為了實現效果,所以文字部分我自己寫了個list用來填充,圖片部分用的都是統一的資原始檔,到時候如果用的朋友可以自行修改資源即可,好了,廢話不多說,看MainActivity中的程式碼。。。

package com.example.alipaydemo;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MainActivity extends Activity {

    private LinearLayout linearLayout;
    private List<String> textList = new ArrayList<String>();
    private static final String TAG = "MainActivity";
    private boolean isParty = true;// 用來標識是否是活動期,對應載入不同的佈局
    private LayoutInflater inflater;
    private Context mContext;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = MainActivity.this;
        inflater = LayoutInflater.from(mContext);
        linearLayout = (LinearLayout) findViewById(R.id.linearlayout);
        initDatas();
    }

    private void initDatas() {
        for (int i = 1; i < 13; i++) {
            textList.add("債權轉讓" + i);
        }

        int index = 0;// 用來記錄擷取的下標

        // 開始填充資料
        if (isParty) {
            // 說明是活動期,載入特殊xml檔案
            View view = inflater.inflate(R.layout.item_party, null);
            ImageView image1 = (ImageView) view.findViewById(R.id.item_image1);
            ImageView image2 = (ImageView) view.findViewById(R.id.item_image2);
            ImageView image3 = (ImageView) view.findViewById(R.id.item_image3);
            TextView text1 = (TextView) view.findViewById(R.id.item_text1);
            TextView text3 = (TextView) view.findViewById(R.id.item_text3);
            List<String> subList = textList.subList(0, 2);

            text1.setText(subList.get(0));
            text3.setText(subList.get(1));

            index = 2;

            linearLayout.addView(view);
        }

        int lines = calLineNum();// 判斷有幾行
        for (int i = 0; i < (isParty ? lines - 1 : lines); i++) {// 0 1
            int total = 0;
            View view = inflater.inflate(R.layout.item_normal, null);
            ImageView image1 = (ImageView) view.findViewById(R.id.image1);
            ImageView image2 = (ImageView) view.findViewById(R.id.image2);
            ImageView image3 = (ImageView) view.findViewById(R.id.image3);
            ImageView image4 = (ImageView) view.findViewById(R.id.image4);
            TextView text1 = (TextView) view.findViewById(R.id.text1);
            TextView text2 = (TextView) view.findViewById(R.id.text2);
            TextView text3 = (TextView) view.findViewById(R.id.text3);
            TextView text4 = (TextView) view.findViewById(R.id.text4);
            List<String> subList = textList.subList(index, textList.size());
            Log.e(TAG, "subList size = : " + subList.size());
            if (subList.size() > 4) {
                List<String> subList2 = subList.subList(total, total + 4);
                image1.setImageResource(R.drawable.ic_launcher);
                image2.setImageResource(R.drawable.ic_launcher);
                image3.setImageResource(R.drawable.ic_launcher);
                image4.setImageResource(R.drawable.ic_launcher);
                text1.setText(subList2.get(0));
                text2.setText(subList2.get(1));
                text3.setText(subList2.get(2));
                text4.setText(subList2.get(3));
            } else if (subList.size() <= 4) {
                int count = subList.size();// 2
                int num = 0;
                if (num < count) {
                    image1.setImageResource(R.drawable.ic_launcher);
                    text1.setText(subList.get(0));
                    num++;
                }
                if (num < count) {
                    image2.setImageResource(R.drawable.ic_launcher);
                    text2.setText(subList.get(1));
                    num++;
                }
                if (num < count) {
                    image3.setImageResource(R.drawable.ic_launcher);
                    text3.setText(subList.get(2));
                    num++;
                }
                if (num < count) {
                    image4.setImageResource(R.drawable.ic_launcher);
                    text4.setText(subList.get(3));
                }
            }

            if (isParty) {
                index = 4 * (i + 1)+2;
            }else {
                index = 4 * (i + 1);
            }
            Log.e(TAG, "index is = " + index);

            linearLayout.addView(view);
        }

    }

    /**
     * 計算有幾行
     * 
     * @return
     */
    public int calLineNum() {
        int num = -1;
        if (isParty) {
            num = textList.size() + 2;// 12
        } else {
            num = textList.size();//
        }
        int line = num / 4;// 3
        int yu = num % 4;// 0

        if (yu > 0 && yu < 4) {
            line = line + 1;
        }
        Log.e(TAG, "line is :" + line);
        return line;
    }
}

怎麼樣,程式碼是不是很簡單,主要的思想就兩步,第一就是根據boolean值來判斷填充的所使用的佈局檔案,第二就是通過計算來填充資料,分別對應下面兩個方法:

// 開始填充資料
        if (isParty) {
            // 說明是活動期,載入特殊xml檔案
            View view = inflater.inflate(R.layout.item_party, null);
            ImageView image1 = (ImageView) view.findViewById(R.id.item_image1);
            ImageView image2 = (ImageView) view.findViewById(R.id.item_image2);
            ImageView image3 = (ImageView) view.findViewById(R.id.item_image3);
            TextView text1 = (TextView) view.findViewById(R.id.item_text1);
            TextView text3 = (TextView) view.findViewById(R.id.item_text3);
            List<String> subList = textList.subList(0, 2);

            text1.setText(subList.get(0));
            text3.setText(subList.get(1));

            index = 2;

            linearLayout.addView(view);
        }
    /**
     * 計算有幾行
     * 
     * @return
     */
    public int calLineNum() {
        int num = -1;
        if (isParty) {
            num = textList.size() + 2;//
        } else {
            num = textList.size();//
        }
        int line = num / 4;//
        int yu = num % 4;//

        if (yu > 0 && yu < 4) {
            line = line + 1;
        }
        Log.e(TAG, "line is :" + line);
        return line;
    }

通過一個boolean值isParty來控制佈局,下面來看看最終的效果,當isParty==true時:
這裡寫圖片描述

當isParty==false時:
這裡寫圖片描述

這裡是有一個小問題的,或者稱不上問題的問題,因為這裡考慮的是如果要出現這個活動也,所以其他模組的數量不會少於2個,所以我這裡並未做2以內的角標越界處理,需要考慮的朋友可以自行處理一下,好了,到這裡整個功能就做完了,這裡廣告的位置並不限制於第一行,也可以是第二行第三行,你想在哪兒就可以在哪兒,只要修改一下判斷位置的演算法即可,所以我覺得還是比較靈活的,程式碼也比較簡單,如果大家有更好的方法,歡迎在下方參與討論,也讓我有所提高,謝謝!

你的支援就是我的動力,歡迎大家熱烈交流~歡迎大家訂閱公眾號,我會不定期更新資源,供大家一起學習。
這裡寫圖片描述