編輯:關於Android編程
RecyclerView是比 ListView 更高級且更具靈活性的組件。 此組件是一個用於顯示龐大數據集的容器,可通過保持有限數量的視圖進行非常有效的滾動操作。 如果您有數據集合,其中的元素將因用戶操作或網絡事件而發生改變,請使用 RecyclerView 小組件。
RecyclerView使用起來很方便因為它:
提供了一種插拔式的體驗,高度的解耦,異常的靈活使用; 顯示的樣式更豐富包括水平,豎直,Grid,瀑布顯示方式; 可以通過ItemDecoration自定義Item間的間隔; 可以通過ItemAnimator自定義Item增、刪動畫(也可設置默認動畫); 代碼內聚不需要手動創建ViewHolder;
compile 'com.android.support:recyclerview-v7:23.4.0'
在xml中添加RecyclerView組件:
構造適配器Adapter:
public class NormalRecyclerViewAdapter extends RecyclerView.Adapter
{
private Context context;
private final LayoutInflater mLayoutInflater;
private String[] mTitles;
public NormalRecyclerViewAdapter(Context context)
{
mTitles = context.getResources().getStringArray(R.array.sports);
this.context = context;
mLayoutInflater = LayoutInflater.from(context);
}
/**
* 導入布局文件
* @param parent
* @param viewType
* @return
*/
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
return new NormalTextViewHolder(mLayoutInflater.inflate(R.layout.item,parent,false));
}
/**
* 綁定數據
* @param holder
* @param position
*/
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
((NormalTextViewHolder)holder).text.setText(mTitles[position]);
//將數據保存在itemView的Tag中,以便點擊時進行獲取
((NormalTextViewHolder)holder).layout.setTag(mTitles[position]);
}
@Override
public int getItemCount()
{
return mTitles.length;
}
public class NormalTextViewHolder extends RecyclerView.ViewHolder
{
private TextView text;
private RelativeLayout layout;
public NormalTextViewHolder(View itemView)
{
super(itemView);
text = (TextView) itemView.findViewById(R.id.text);
layout = (RelativeLayout) itemView.findViewById(R.id.layout);
layout.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
Toast.makeText(context, ""+v.getTag(), Toast.LENGTH_SHORT).show();
}
});
}
}
}
item.xml布局,就一個textView:.RecyclerView.Adapter主要用於處理數據集合並負責綁定視圖;ViewHolder持有item所有的用於綁定數據的View;
activity中進行簡單的設置:
recyclerView = (RecyclerView) findViewById(R.id.my_recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new NormalRecyclerViewAdapter(this);
recyclerView.setAdapter(adapter);
效果圖:
recyclerview提供這些內置的布局管理器:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCglpbmVhcmxheW91dG1hbmFnZXIgz9TKvrS51rG59ravwdCx7bvyy67GvbXEz+7Ev6GjIGdyaWRsYXlvdXRtYW5hZ2VyIM/Uyr7U2tK7uPbN+Ljxz+7Ev6GjIHN0YWdnZXJlZGdyaWRsYXlvdXRtYW5hZ2VyIM/Uyr7U2r27tO3N+Ljxz+7Ev6GjPC9ibG9ja3F1b3RlPg0KPHA+LSDJ6NbDbGF5b3V0bWFuYWdlcs6qZ3JpZGxheW91dG1hbmFnZXLKsaOs0Ke5+8jnz8KjujwvcD4NCjxwPjxpbWcgYWx0PQ=="這裡寫圖片描述" src="/uploadfile/Collfiles/20160602/20160602091037256.gif" title="\" />
Staggeredgridlayoutmanager 這個效果大家可以自己試試,後面也會介紹;
2.添加分割線
突然發現列表出來是出來了,可是,沒有分割線啊,不要驚慌,recyclerView需要單獨處理分割線,提供了下面這個方法用來設置分割線的風格:
recyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST));
下面是官方給的分割線的例子,DividerItemDecoration,java:
public class DividerItemDecoration extends RecyclerView.ItemDecoration { private static final int[] ATTRS = new int[] { android.R.attr.listDivider }; public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL; public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL; private Drawable mDivider; private int mOrientation; public DividerItemDecoration(Context context, int orientation) { final TypedArray a = context.obtainStyledAttributes(ATTRS); mDivider = a.getDrawable(0); a.recycle(); setOrientation(orientation); } public void setOrientation(int orientation) { if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) { throw new IllegalArgumentException("invalid orientation"); } mOrientation = orientation; } @Override public void onDraw(Canvas c, RecyclerView parent) { if (mOrientation == VERTICAL_LIST) { drawVertical(c, parent); } else { drawHorizontal(c, parent); } } public void drawVertical(Canvas c, RecyclerView parent) { final int left = parent.getPaddingLeft(); final int right = parent.getWidth() - parent.getPaddingRight(); final int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { final View child = parent.getChildAt(i); RecyclerView v = new RecyclerView( parent.getContext()); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child .getLayoutParams(); final int top = child.getBottom() + params.bottomMargin; final int bottom = top + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } public void drawHorizontal(Canvas c, RecyclerView parent) { final int top = parent.getPaddingTop(); final int bottom = parent.getHeight() - parent.getPaddingBottom(); final int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { final View child = parent.getChildAt(i); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child .getLayoutParams(); final int left = child.getRight() + params.rightMargin; final int right = left + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } @Override public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) { if (mOrientation == VERTICAL_LIST) { outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); } else { outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); } } }
效果圖:
3.加載不同的View
開始之前,這裡要注意的就是函數onCreateViewHolder(ViewGroup parent, int viewType)這裡的第二個參數就是View的類型,可以根據這個類型判斷去創建不同item的ViewHolder。我們可以通過重寫 getItemViewType方法是用來獲取當前項Item(position參數)是哪種類型的布局。
主xml布局很簡單,就一個RecyclerView組件:本例子結合cardview來實現,對cardview不熟悉的同學可以看下cardview講解;
item布局文件item_image.xml
關鍵的adapter代碼:
Activity中進行綁定和顯示:public class TypeRecyclerViewAdapter extends RecyclerView.Adapter
{ private String imageOne = "http://5.133998.com/2014/pic/000/363/18107c4b46aa8a182776746ff43e49bf.jpg"; private String imageTwo = "http://img3.imgtn.bdimg.com/it/u=3954782107,4019560836&fm=21&gp=0.jpg"; private boolean flag = false; public static enum ITEM_TYPE { ITEM_TYPE_IMAGE, ITEM_TYPE_TEXT } private Context context; private final LayoutInflater mLayoutInflater; private String[] mTitles; public TypeRecyclerViewAdapter(Context context) { mTitles = context.getResources().getStringArray(R.array.sports); this.context = context; mLayoutInflater = LayoutInflater.from(context); } /** * 導入布局文件 * @param parent * @param viewType * @return */ @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == ITEM_TYPE.ITEM_TYPE_IMAGE.ordinal()) { return new ImageViewHolder(mLayoutInflater.inflate(R.layout.item_image, parent, false)); } else { return new NormalTextViewHolder(mLayoutInflater.inflate(R.layout.item_card, parent, false)); } } /** * 綁定數據 * @param holder * @param position */ @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { //判斷holder的類型,來顯示不同的View if (holder instanceof NormalTextViewHolder) { ((NormalTextViewHolder) holder).text.setText(mTitles[position]); //將數據保存在itemView的Tag中,以便點擊時進行獲取 ((NormalTextViewHolder) holder).layout.setTag(mTitles[position]); } else if (holder instanceof ImageViewHolder) { ((ImageViewHolder)holder).textView.setText(mTitles[position]); //將數據保存在itemView的Tag中,以便點擊時進行獲取 ((ImageViewHolder)holder).layout.setTag(mTitles[position]); /** * 交叉加載圖片,測試用 */ if(flag) { ImageLoader.getInstance().displayImage(imageOne,((ImageViewHolder)holder).imageView); flag = !flag; } else { ImageLoader.getInstance().displayImage(imageTwo,((ImageViewHolder)holder).imageView); flag = !flag; } } } @Override public int getItemCount() { return mTitles.length; } @Override public int getItemViewType(int position) { //返回類型標記 return position % 2 == 0 ? ITEM_TYPE.ITEM_TYPE_IMAGE.ordinal() : ITEM_TYPE.ITEM_TYPE_TEXT.ordinal(); } /** * 純textView布局holder */ public class NormalTextViewHolder extends RecyclerView.ViewHolder { private TextView text; private RelativeLayout layout; public NormalTextViewHolder(View itemView) { super(itemView); text = (TextView) itemView.findViewById(R.id.text); layout = (RelativeLayout) itemView.findViewById(R.id.layout); layout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(context, ""+v.getTag(), Toast.LENGTH_SHORT).show(); } }); } } /** * 帶圖片的布局holder */ public class ImageViewHolder extends RecyclerView.ViewHolder { private TextView textView; private ImageView imageView; private LinearLayout layout; public ImageViewHolder(View itemView) { super(itemView); imageView = (ImageView) itemView.findViewById(R.id.image); textView = (TextView) itemView.findViewById(R.id.image_text); layout = (LinearLayout) itemView.findViewById(R.id.layout); layout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(context, ""+v.getTag(), Toast.LENGTH_SHORT).show(); } }); } } } 效果圖:recyclerView = (RecyclerView) findViewById(R.id.type_recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(this)); adapter = new TypeRecyclerViewAdapter(this); recyclerView.setAdapter(adapter);
4.插入刪除動畫
RecyclerView提供了設置動畫的方法,我們只需要通過setItemAnimator方法即可設置Item插入和刪除的動畫;
//添加默認動畫 recyclerView.setItemAnimator(new DefaultItemAnimator());
之前的數據源用的是個String數組,無法添加數據,轉為list後添加;
效果圖:/** * 添加數據 * @param content * @param position */ public void addItem(String content, int position) { titleList.add(position,content); notifyItemInserted(position); //Attention! } /** * 刪除數據 * @param content */ public void removeItem(String content) { int position = titleList.indexOf(content); titleList.remove(position); notifyItemRemoved(position);//Attention! }
基本使用先介紹這麼多,歡迎看官批評討論!
AndroidRecyclerViewDemo">源碼下載
EditText在API中的結構 java.lang.Object android.view.View android.widget.T
寫BlueStacks安卓模擬器腳本的一般步驟,其實BlueStacks安卓模擬器腳本不是很難,只要跟下面步驟來,一步一步走,就學了。BlueStacks安
我們在選購安卓手機的時候,參數中最容易犯暈的就是ROM和RAM了,許多朋友都不了解是什麼意思,廠家也借助這一點來大做文章,下面我就給大家來簡單的介紹一下其中
1.返回棧Android 是使用任務(Task)來管理活動的,一個任務就是一組存放在棧裡的活動的集合,這個棧也被稱作返回棧(Back Stack)。棧是一種後進先出的數據