這次,我要實現個類似京東商城android客戶端上商品圖片展示的組件,如下圖展示愛瘋4的組件,注意,不包含小箭頭。【由於不方便上傳圖片,就只能使用網上圖片了】
首先,我先實現上圖的效果,要實現這種組件就必須繼承AdapterView<ListAdapter>,實現構造方法、onMeasure()、onLayout()、setAdapter()方法。看代碼:
public class ImageWallView extends AdapterView<ListAdapter>{
private ListAdapter mAdapter;
private int unitWidth; //每個child的寬
private int numColumns; //屏幕展示的孩子的數目
/**
* 構造方法
*/
public ImageWallView(Context context) {
super(context);
}
public ImageWallView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ImageWallView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* 繼承AdapterView需要實現以下四個方法
* getAdapter()
* setAdapter(ListAdapter adapter)
* getSelectedView()
* setSelection(int position)
*/
@Override
public ListAdapter getAdapter() {
return mAdapter;
}
@Override
public void setAdapter(ListAdapter adapter) {
this.mAdapter = adapter;
//把所有的child添加到佈局中
for(int i=0;i<mAdapter.getCount();i++){
View child = mAdapter.getView(i,null,this);
addViewInLayout(child,i,child.getLayoutParams());
}
}
@Override
public View getSelectedView() {
return null;
}
@Override
public void setSelection(int position) { }
/**
* 設置佈局
*/
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int childCount = getChildCount();
int pLeft = 0;
int pTop = 0;
int childWidth=0;
int childHeight=0;
if(childCount>0){
View child = getChildAt(0);
LayoutParams p = child.getLayoutParams();
childWidth = p.width + child.getPaddingLeft() + child.getPaddingRight() ; //組件的寬度
childHeight = p.height + child.getPaddingTop() + child.getPaddingBottom(); //組件的高度
numColumns = (getMeasuredWidth() - getPaddingLeft() - getPaddingRight())/childWidth; //計算屏幕中可以放置幾個child
int spacing = (getMeasuredWidth() - getPaddingLeft() - getPaddingRight() - numColumns * childWidth)/numColumns; //計算child之間的平均空隙
int spacingLR = (getPaddingLeft() + getPaddingRight() )/2;//組件左右邊的平均空隙
if(spacing > spacingLR){ // 當組件間的均距離大於兩邊的組件左右的空隙的平均值時,調整一下,這個只是爲了樣式,可越過
int outSpacing = spacing - spacingLR;
setPadding(spacingLR+outSpacing,getPaddingTop(),spacingLR+outSpacing,getPaddingBottom());
}
unitWidth = childWidth + spacing ;
}
for(int i=0;i<childCount;i++){
View child = getChildAt(i);
pLeft = getPaddingLeft() + i * unitWidth+(int)offset; //child距離左端的距離
pTop = getPaddingTop(); //child距離頂端的距離
child.layout(pLeft,pTop,pLeft + childWidth,pTop + childHeight);
}
}
/**
* 設置大小
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//設置寬度和高度
setMeasuredDimension(
getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec), //getDefaultSize() 獲取參數兩個值中較大的那個
getDefaultSize(getSuggestedMinimumHeight(),heightMeasureSpec)
);
}
}
onMeasure() 中設置了組件的大小
onLayout() 中設置了傳進來的ListAdapter內容怎樣在組件中分佈
setAdapter() 中把ListAdapter的內容加入組件中
使用:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:demo="http://schemas.android.com/apk/res/com.wxg.activity"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<com.wxg.view.ImageWallView
android:layout_width="fill_parent"
android:layout_height="100dp"
android:paddingLeft="10dp"
android:paddingTop="5dp"
android:paddingRight="10dp"
android:id="@+id/imageWallView"
android:background="#ffffff"
/>
<TextView
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:gravity="center"
android:text="圖片牆組件"
android:textColor="#ffffff"
android:textSize="25sp"/>
</LinearLayout>
有個地方需要注意,使用組件時要自定義Adapter,不能使用系統自帶的Adapter。
這樣,就可以實現想要的樣式了,但是現在圖片還不能隨着手勢滑動,在下篇中會實現隨手勢滑動。