這裏要說的是RecyclerView的使用,希望能助你完全理解RecyclerView,把它運用到項目中,當然這裏也會提供你簡便的寫法,要知道每次都寫個adapter費時又費力,只能說本人很懶,於是在網上找方法,聰明的你應該知道是怎麼做了吧,不錯,就是打造一個通用的adapter。這裏先賣個關子,要知道就繼續往下看吧。
概述
RecyclerView 是Android L版本中新添加的一個可用來替換ListView和GridView的SDK,它的靈活性與可替代性比ListView和GridView更好。能夠在有限的窗口中展示大數據集合的靈活視圖,這就是所謂的RecyclerView吧。
如果你想使用RecyclerView,你將需要使用以下幾點:
*RecyclerView.Adapter – 處理數據收集並將其綁定到視圖
*ViewHolder – 持有所有的用於綁定數據或者需要操作的View
*LayoutManager – 負責擺放視圖等相關操作
*ItemDecoration – 負責繪製Item附近的分割線
*ItemAnimator – 爲item的一般操作添加動畫效果,比如添加或刪除條目
想看最原始的使用方法,想知道更多的細節,請看這裏
如果你實在看不懂英文的話,這篇文章也能很好的說明使用方法,請看這裏
RecyclerView的簡單使用方法
這裏只給出單種item的示例代碼,更多使用方法()可看萬能適配器,這裏很感謝鴻神的開源,他的博客都很不錯,值得學習,各位客官,下面就請聽我步步道來:
- 添加依賴
在AS的 build.gradle 中添加依賴,然後同步一下就可以引入依賴包(記得換上你的最新版本):
dependencies {
...
compile 'com.android.support:recyclerview-v7:23.3.0'
}
- 佈局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"/>
</RelativeLayout>
- 通用的ViewHolder
這裏也適用於listview
public class ViewHolder extends RecyclerView.ViewHolder
{
private SparseArray<View> mViews;
private int mPosition;
private View mConvertView;
private Context mContext;
private int mLayoutId;
public ViewHolder(Context context, View itemView, ViewGroup parent, int position)
{
super(itemView);
mContext = context;
mConvertView = itemView;
mPosition = position;
mViews = new SparseArray<View>();
mConvertView.setTag(this);
}
public static ViewHolder get(Context context, View convertView,
ViewGroup parent, int layoutId, int position)
{
if (convertView == null)
{
View itemView = LayoutInflater.from(context).inflate(layoutId, parent,
false);
ViewHolder holder = new ViewHolder(context, itemView, parent, position);
holder.mLayoutId = layoutId;
return holder;
} else
{
ViewHolder holder = (ViewHolder) convertView.getTag();
holder.mPosition = position;
return holder;
}
}
/**
* 通過viewId獲取控件
*
* @param viewId
* @return
*/
public <T extends View> T getView(int viewId)
{
View view = mViews.get(viewId);
if (view == null)
{
view = mConvertView.findViewById(viewId);
mViews.put(viewId, view);
}
return (T) view;
}
public View getConvertView()
{
return mConvertView;
}
/**
* 設置TextView的值
*
* @param viewId
* @param text
* @return
*/
public ViewHolder setText(int viewId, String text)
{
TextView tv = getView(viewId);
tv.setText(text);
return this;
}
public ViewHolder setImageResource(int viewId, int resId)
{
ImageView view = getView(viewId);
view.setImageResource(resId);
return this;
}
public ViewHolder setImageBitmap(int viewId, Bitmap bitmap)
{
ImageView view = getView(viewId);
view.setImageBitmap(bitmap);
return this;
}
public ViewHolder setImageDrawable(int viewId, Drawable drawable)
{
ImageView view = getView(viewId);
view.setImageDrawable(drawable);
return this;
}
public ViewHolder setBackgroundColor(int viewId, int color)
{
View view = getView(viewId);
view.setBackgroundColor(color);
return this;
}
public ViewHolder setBackgroundRes(int viewId, int backgroundRes)
{
View view = getView(viewId);
view.setBackgroundResource(backgroundRes);
return this;
}
public ViewHolder setTextColor(int viewId, int textColor)
{
TextView view = getView(viewId);
view.setTextColor(textColor);
return this;
}
public ViewHolder setTextColorRes(int viewId, int textColorRes)
{
TextView view = getView(viewId);
view.setTextColor(mContext.getResources().getColor(textColorRes));
return this;
}
@SuppressLint("NewApi")
public ViewHolder setAlpha(int viewId, float value)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
{
getView(viewId).setAlpha(value);
} else
{
// Pre-honeycomb hack to set Alpha value
AlphaAnimation alpha = new AlphaAnimation(value, value);
alpha.setDuration(0);
alpha.setFillAfter(true);
getView(viewId).startAnimation(alpha);
}
return this;
}
public ViewHolder setVisible(int viewId, boolean visible)
{
View view = getView(viewId);
view.setVisibility(visible ? View.VISIBLE : View.GONE);
return this;
}
public ViewHolder linkify(int viewId)
{
TextView view = getView(viewId);
Linkify.addLinks(view, Linkify.ALL);
return this;
}
public ViewHolder setTypeface(Typeface typeface, int... viewIds)
{
for (int viewId : viewIds)
{
TextView view = getView(viewId);
view.setTypeface(typeface);
view.setPaintFlags(view.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG);
}
return this;
}
public ViewHolder setProgress(int viewId, int progress)
{
ProgressBar view = getView(viewId);
view.setProgress(progress);
return this;
}
public ViewHolder setProgress(int viewId, int progress, int max)
{
ProgressBar view = getView(viewId);
view.setMax(max);
view.setProgress(progress);
return this;
}
public ViewHolder setMax(int viewId, int max)
{
ProgressBar view = getView(viewId);
view.setMax(max);
return this;
}
public ViewHolder setRating(int viewId, float rating)
{
RatingBar view = getView(viewId);
view.setRating(rating);
return this;
}
public ViewHolder setRating(int viewId, float rating, int max)
{
RatingBar view = getView(viewId);
view.setMax(max);
view.setRating(rating);
return this;
}
public ViewHolder setTag(int viewId, Object tag)
{
View view = getView(viewId);
view.setTag(tag);
return this;
}
public ViewHolder setTag(int viewId, int key, Object tag)
{
View view = getView(viewId);
view.setTag(key, tag);
return this;
}
public ViewHolder setChecked(int viewId, boolean checked)
{
Checkable view = (Checkable) getView(viewId);
view.setChecked(checked);
return this;
}
/**
* 關於事件的
*/
public ViewHolder setOnClickListener(int viewId,
View.OnClickListener listener)
{
View view = getView(viewId);
view.setOnClickListener(listener);
return this;
}
public ViewHolder setOnTouchListener(int viewId,
View.OnTouchListener listener)
{
View view = getView(viewId);
view.setOnTouchListener(listener);
return this;
}
public ViewHolder setOnLongClickListener(int viewId,
View.OnLongClickListener listener)
{
View view = getView(viewId);
view.setOnLongClickListener(listener);
return this;
}
public void updatePosition(int position)
{
mPosition = position;
}
public int getLayoutId()
{
return mLayoutId;
}
}
- 通用的Adapter
public abstract class CommonAdapter<T> extends RecyclerView.Adapter<ViewHolder>
{
protected Context mContext;
protected int mLayoutId;
protected List<T> mDatas;
protected LayoutInflater mInflater;
private OnItemClickListener mOnItemClickListener;
public void setOnItemClickListener(OnItemClickListener onItemClickListener)
{
this.mOnItemClickListener = onItemClickListener;
}
public CommonAdapter(Context context, int layoutId, List<T> datas)
{
mContext = context;
mInflater = LayoutInflater.from(context);
mLayoutId = layoutId;
mDatas = datas;
}
@Override
public ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType)
{
ViewHolder viewHolder = ViewHolder.get(mContext, null, parent, mLayoutId, -1);
setListener(parent, viewHolder, viewType);
return viewHolder;
}
protected int getPosition(RecyclerView.ViewHolder viewHolder)
{
return viewHolder.getAdapterPosition();
}
protected boolean isEnabled(int viewType)
{
return true;
}
protected void setListener(final ViewGroup parent, final ViewHolder viewHolder, int viewType)
{
if (!isEnabled(viewType)) return;
viewHolder.getConvertView().setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
if (mOnItemClickListener != null)
{
int position = getPosition(viewHolder);
mOnItemClickListener.onItemClick(parent, v, mDatas.get(position), position);
}
}
});
viewHolder.getConvertView().setOnLongClickListener(new View.OnLongClickListener()
{
@Override
public boolean onLongClick(View v)
{
if (mOnItemClickListener != null)
{
int position = getPosition(viewHolder);
return mOnItemClickListener.onItemLongClick(parent, v, mDatas.get(position), position);
}
return false;
}
});
}
@Override
public void onBindViewHolder(ViewHolder holder, int position)
{
holder.updatePosition(position);
convert(holder, mDatas.get(position));
}
public abstract void convert(ViewHolder holder, T t);
@Override
public int getItemCount()
{
return mDatas.size();
}
}
對了,別忘了給item添加點擊處理
public interface OnItemClickListener<T> {
void onItemClick(ViewGroup parent, View view, T t, int position);
boolean onItemLongClick(ViewGroup parent, View view, T t, int position);
}
- RecyclerView的使用
初始化組件
mRecyclerView = (RecyclerView)findViewById(R.id.my_recycler_view);
//創建默認的線性LayoutManager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
//如果可以確定每個item的高度是固定的,設置這個選項可以提高性能
mRecyclerView.setHasFixedSize(true);
//設置分割線
mRecyclerView..addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));
分割線
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, RecyclerView.State state) {
if(mOrientation == VERTICAL_LIST){
drawVertical(c, parent);
}else{
drawHorizontal(c, parent);
}
}
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);
}
}
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);
}
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
if(mOrientation == VERTICAL_LIST){
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
}else {
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
}
}
}
設置adapter,這裏的String可根據你項目要求換成你所需的Bean都行
mRecyclerView.setAdapter(new CommonAdapter<String>(this, R.layout.item_list, mDatas)
{
@Override
public void convert(ViewHolder holder, String s)
{
holder.setText(R.id.id_item_list_title, s);
}
});
以上就是RecyclerView的簡便使用了,如果要在一個頁面再新建一個RecyclerView,只需要在activity或fragment中直接setAdapter()調用通用適配器,這樣可以簡便很多,那麼有了上面的代碼後,你知道怎麼添加多選功能嗎?如不清楚,再聽我慢慢道來:
- 首先在ViewHolder中添加選中的實現方式,這裏以點擊某view實現,供實現adapter時調用
/**
* 選擇item
* 實現多選
*/
public ViewHolder setSelectListener(int viewId,
View.OnClickListener listener)
{
View view = getView(viewId);
view.setOnClickListener(listener);
return this;
}
- 在CommonAdapter類中添加幾個方法,以供調用者切換選中效果或者清除選中效果等。。
private SparseBooleanArray selectedItems;//記錄選中的position
/**
* 判讀是否選中
*/
public boolean isSelected(int position){
return getSelectedItems().contains(position);
}
/**
* 切換選中或取消選中
*/
public void switchSelectedState(int position){
if(selectedItems.get(position, false)){
selectedItems.delete(position);
}else{
selectedItems.put(position,true);
}
notifyItemChanged(position);
}
/**
* 清除所有選中item的標記
*/
public void clearSelectedState(){
List<Integer> selection = getSelectedItems();
selectedItems.clear();
for(Integer i : selection){
notifyItemChanged(i);
}
}
/**
* 全選
*/
public void selectAllItems(){
clearSelectedState();
for(int i = 0; i < getItemCount(); i++){
selectedItems.put(i,true);
notifyItemChanged(i);
}
}
/**
* 獲取item數目
*/
public int getSelectedItemCount(){
return selectedItems.size();
}
/**
* 獲取選中的items
*/
public List<Integer> getSelectedItems(){
List<Integer> items = new ArrayList<>(selectedItems.size());
for(int i = 0; i < selectedItems.size(); i++){
items.add(selectedItems.keyAt(i));
}
return items;
}
最後在setAdapter時實現你多選的效果
//設置選中狀態
if(omsAdapter.isSelected(holder.getItemPosition())) {
holder.setImageResource(R.id.img_isSelect, R.drawable.choiced_ic);
}else{
holder.setImageResource(R.id.img_isSelect, R.drawable.no_choice_ic);
}
//設置選中事件
holder.setSelectListener(R.id.img_isSelect, new View.OnClickListener() {
@Override
public void onClick(View v) {
omsAdapter.switchSelectedState(holder.getItemPosition());//切換選中
}
});
以上就是本次博客的所有內容了,有誤請各位客官指出,在下會繼續虛心學習,雖然本人有點懶,但是隻要有簡便方法實現所需功能又不失性能,則會選擇去重構。