RecyclerView封裝詳解完美用法一
阿新 • • 發佈:2019-01-28
通過對RecyclerView的瞭解,個人認為此控制元件適用於需要listview與GridView切換的介面以及瀑布流介面。
第一篇主要是listView與Gridview切換程式碼:
一、先上RecyclerView的通用ViewHolder:
package com.example.recyclerview; import android.graphics.Bitmap; import android.support.v7.widget.RecyclerView; import android.util.SparseArray; import android.view.View; import二、然後是介面卡:android.widget.ImageView; import android.widget.TextView; /** * Created by 11981 on 2016/5/30. * RecyclerView通用ViewHolder */ public class MyViewHolder extends RecyclerView.ViewHolder { private SparseArray<View> mViews; public MyViewHolder(View itemView) { super(itemView); mViews= newSparseArray<View>(); } //通過viewId獲取控制元件 public <T extends View> T getView(int viewId) { View view = mViews.get(viewId); if (view == null) { view = itemView.findViewById(viewId); mViews.put(viewId, view); } return (T) view; } /** * 設定TextView的值*/ public MyViewHolder setText(int viewId,String text){ TextView tv= getView(viewId); tv.setText(text); return this; } public MyViewHolder setImageResource(int viewId,int resId){ ImageView view= getView(viewId); view.setImageResource(resId); return this; } public MyViewHolder setImageBitamp(int viewId,Bitmap bitmap){ ImageView view= getView(viewId); view.setImageBitmap(bitmap); return this; } public MyViewHolder setImageURI(int viewId,String uri){ ImageView view= getView(viewId); // Imageloader.getInstance().loadImg(view,uri); return this; } }
package com.example.recyclerview; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import java.util.List; /** * Created by 11981 on 2016/5/26. * recyclerview_list_grid介面卡 */ public abstract class SimpleAdapters extends RecyclerView.Adapter<MyViewHolder> { private LayoutInflater mInflater; public List<DataDTO> mDatas; private int mlayoutId; public interface OnItemClickListener { void onItemClick(View view, int position); void onItemLongClick(View view, int position); } private OnItemClickListener onItemClickListener; public void setOnItemClickListener(OnItemClickListener listener) { this.onItemClickListener = listener; } public SimpleAdapters(Context context, List<DataDTO> datas, int layoutId) { this.mDatas = datas; this.mlayoutId = layoutId; mInflater = LayoutInflater.from(context); } @Override public int getItemCount() { return mDatas.size(); } @Override public void onBindViewHolder(final MyViewHolder holder, final int position) { convert(holder,mDatas.get(position)); setUpItemEvent(holder); } public abstract void convert(MyViewHolder holder,DataDTO datadto); public void setUpItemEvent(final MyViewHolder holder) { if (onItemClickListener != null) { holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //這個獲取位置的方法,防止新增刪除導致位置不變 int layoutPosition = holder.getAdapterPosition(); onItemClickListener.onItemClick(holder.itemView, layoutPosition); } }); //longclick holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { int layoutPosition = holder.getAdapterPosition(); onItemClickListener.onItemLongClick(holder.itemView, layoutPosition); return false; } }); } } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { MyViewHolder viewHolder = new MyViewHolder(mInflater.inflate(mlayoutId, parent, false)); return viewHolder; } public void addData(int pos,DataDTO datas) { mDatas.add(pos, datas); notifyItemInserted(pos); } public void deleteData(int pos) { mDatas.remove(pos); notifyItemRemoved(pos); } }三、最後是主類:
package com.example.recyclerview; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.StaggeredGridLayoutManager; import android.view.View; import android.widget.TextView; import android.widget.Toast; import java.util.ArrayList; import java.util.List; /** * recyclerview_list_grid主類 */ public class MainActivity extends AppCompatActivity implements View.OnClickListener { private RecyclerView mRecyclerView; private List<DataDTO> mDatas; private SimpleAdapters mAdapter; private TextView mlist, mgrid, mhgrid, mstag,madd,mdel; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initDatas(); initViews(); mAdapter=new SimpleAdapters(this, mDatas, R.layout.item_single_view) { @Override public void convert(MyViewHolder holder, DataDTO datadto) { holder.setText(R.id.id_tv,datadto.getAaa()).setImageResource(R.id.id_img,datadto.getBbb()); } }; mRecyclerView.setAdapter(mAdapter); //設定recyclerview佈局管理器 LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false); mRecyclerView.setLayoutManager(linearLayoutManager); mRecyclerView.setItemAnimator(new DefaultItemAnimator()); mAdapter.setOnItemClickListener(new SimpleAdapters.OnItemClickListener() { @Override public void onItemClick(View view, int position) { Toast.makeText(MainActivity.this,"click:"+position,Toast.LENGTH_SHORT).show(); } @Override public void onItemLongClick(View view, int position) { Toast.makeText(MainActivity.this,"longclick:"+position,Toast.LENGTH_SHORT).show(); } }); //設定recycler的Item分割線 //listview轉gridview沒有列的分割 // mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST)); } private void initDatas() { mDatas = new ArrayList<DataDTO>(); DataDTO data=new DataDTO(); for (int i = 0; i <20 ; i++) { data.setAaa("aaaaa"); data.setBbb(R.drawable.ic_menu_delete); mDatas.add(data); } } private void initViews() { mRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerview); mlist = (TextView) findViewById(R.id.action_listview); mlist.setOnClickListener(this); mgrid = (TextView) findViewById(R.id.action_gridview); mgrid.setOnClickListener(this); mhgrid = (TextView) findViewById(R.id.action_hor_gridview); mhgrid.setOnClickListener(this); mstag = (TextView) findViewById(R.id.action_staggered); mstag.setOnClickListener(this); madd=(TextView) findViewById(R.id.action_add); madd.setOnClickListener(this); mdel=(TextView) findViewById(R.id.action_delete); mdel.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.action_listview: mRecyclerView.setLayoutManager( new LinearLayoutManager(this) ); break; case R.id.action_gridview: //二參為列數 mRecyclerView.setLayoutManager( new GridLayoutManager(this, 3) ); break; case R.id.action_hor_gridview: //一參為行數 mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager (8, StaggeredGridLayoutManager.HORIZONTAL)); break; case R.id.action_staggered: Intent intent =new Intent(); startActivity(intent.setClass(this,StaggereGridLayoutActivity.class)); break; case R.id.action_add: DataDTO datas = new DataDTO(); datas.setAaa("Insert One"); datas.setBbb(R.drawable.ic_menu_delete); mAdapter.addData(1,datas); break; case R.id.action_delete: mAdapter.deleteData(1); break; default: break; } } }四、RecyclerView依賴工具類:
package com.example.recyclerview; /* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.View; /** * This class is from the v7 samples of the Android SDK. It's not by me! * <p/> * See the license above for details. * RecyclerView依賴工具類 */ 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) { // Log.v("recyclerview - itemdecoration", "onDraw()"); 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); } } }五、實體類:
package com.example.recyclerview; /** * Created by 11981 on 2016/5/29. * 實體類 */ public class DataDTO { private String aaa; private int bbb; public int getBbb() { return bbb; } public void setBbb(int bbb) { this.bbb = bbb; } public String getAaa() { return aaa; } public void setAaa(String aaa) { this.aaa = aaa; } }六、其它的程式碼:
drawable下:
divider_two.xml:這個是自定義的分割線(listview)
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <size android:height="4dp" /> <gradient android:centerColor="#ff00ff00" android:endColor="#ffff0000" android:startColor="#ff0000ff" android:type="linear"/> </shape>item_bg.xml:點選效果
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:drawable="@color/state_item_pressed"/> <item android:drawable="@color/state_item_normal"/> </selector>還有一張圖片(自行設定)名稱:ic_menu_delete.png
Layout下:
主類佈局:
<?xml version="1.0" encoding="utf-8"?> <LinearLayoutxmlns: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" android:orientation="vertical" tools:context="com.example.recyclerview.MainActivity"> <LinearLayoutandroid:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:id="@+id/action_listview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:textSize="25sp" android:layout_weight="1" android:text="list" /> <TextView android:id="@+id/action_gridview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:textSize="25sp" android:layout_weight="1" android:text="grid" /> <TextView android:id="@+id/action_hor_gridview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:textSize="25sp" android:layout_weight="1" android:text="hgrid" /> <TextView android:id="@+id/action_staggered" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:textSize="25sp" android:layout_weight="1" android:text="stag" /> <TextView android:id="@+id/action_add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:textSize="25sp" android:layout_weight="1" android:text="add" /> <TextView android:id="@+id/action_delete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:textSize="25sp" android:layout_weight="1" android:text="del" /> </LinearLayout> <android.support.v7.widget.RecyclerView android:id="@+id/id_recyclerview" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>item佈局:item_single_view.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:background="@drawable/item_bg" android:layout_width="match_parent" android:orientation="vertical" android:layout_margin="3dp" android:layout_height="72dp"> <TextView android:id="@+id/id_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="測試資料"/> <ImageView android:id="@+id/id_img" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>values下:
color中:
<color name="state_item_pressed">#AAff0000</color> <color name="state_item_normal">#44ff0000</color>style中;
<item name="android:windowNoTitle">true</item> <item name="android:windowActionBar">false</item> <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item>
下一篇寫RecyclerView實現瀑布流。