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以內的角標越界處理,需要考慮的朋友可以自行處理一下,好了,到這裡整個功能就做完了,這裡廣告的位置並不限制於第一行,也可以是第二行第三行,你想在哪兒就可以在哪兒,只要修改一下判斷位置的演算法即可,所以我覺得還是比較靈活的,程式碼也比較簡單,如果大家有更好的方法,歡迎在下方參與討論,也讓我有所提高,謝謝!
你的支援就是我的動力,歡迎大家熱烈交流~歡迎大家訂閱公眾號,我會不定期更新資源,供大家一起學習。