channel布局
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="zhanghaijiao.bawei.com.recylerview_demo1.MainActivity" android:paddingBottom="10dp" android:paddingLeft="10dp" android:paddingRight="10dp" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="关闭" android:padding="8dp" android:layout_alignParentRight="true" android:id="@+id/tv_close"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:id="@+id/lin_top" android:layout_below="@+id/tv_close"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="我的频道" android:id="@+id/tv_channel" android:layout_marginRight="5dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="点击删除频道" android:textSize="10sp" android:id="@+id/tv_del" /> </LinearLayout> <android.support.v7.widget.RecyclerView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/rev" android:layout_below="@+id/lin_top" android:layout_marginBottom="30dp"></android.support.v7.widget.RecyclerView> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:id="@+id/lin_bottom" android:layout_below="@+id/rev"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="频道推荐" android:id="@+id/tv_recommend_channel" android:layout_marginRight="5dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="点击添加频道" android:textSize="10sp" android:id="@+id/tv_add" /> </LinearLayout> <android.support.v7.widget.RecyclerView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/rev_recommend" android:layout_below="@+id/lin_bottom"></android.support.v7.widget.RecyclerView> </RelativeLayout>
Mainactivity布局
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="zhanghaijiao.bawei.com.recylerview_demo1.MainActivity" android:padding="16dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:id="@+id/lin_top"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="我的频道" android:id="@+id/tv_channel" android:layout_marginRight="5dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="点击删除频道" android:textSize="10sp" android:id="@+id/tv_del" /> </LinearLayout> <android.support.v7.widget.RecyclerView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/rev" android:layout_below="@+id/lin_top"></android.support.v7.widget.RecyclerView> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:id="@+id/lin_bottom" android:layout_below="@+id/rev"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="频道推荐" android:id="@+id/tv_recommend_channel" android:layout_marginRight="5dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="点击添加频道" android:textSize="10sp" android:id="@+id/tv_add" /> </LinearLayout> <android.support.v7.widget.RecyclerView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/rev_recommend" android:layout_below="@+id/lin_bottom"></android.support.v7.widget.RecyclerView> </RelativeLayout>
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:layout_width="80dp" android:layout_height="30dp" android:gravity="center" android:id="@+id/tv" android:background="#ccc" android:layout_margin="7dp"/> </RelativeLayout>
MainActivity代码------
public class MainActivity extends AppCompatActivity { private List<String> tabDatas=new ArrayList<>(); private List<String> tabRecommend=new ArrayList<>(); private MyRecylerView recycleAdapter; private MyRecylerView recommendRecycleAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); RecyclerView recyclerView=findViewById(R.id.rev); final RecyclerView recyclerViewRecommend = findViewById(R.id.rev_recommend); initData(); //1.创建布局管理器 // LinearLayoutManager manager=new LinearLayoutManager(this); // manager.setOrientation(LinearLayoutManager.HORIZONTAL);//设置方向 // recyclerView.setLayoutManager(manager); GridLayoutManager manager=new GridLayoutManager(this,3); manager.setOrientation(GridLayoutManager.VERTICAL);//方向设置为横向,spanCount代表行数 recyclerView.setLayoutManager(manager); //布局适配器对象不能重复使用 GridLayoutManager manager1=new GridLayoutManager(this,3); manager.setOrientation(GridLayoutManager.VERTICAL);//方向设置为横向,spanCount代表行数 recyclerViewRecommend.setLayoutManager(manager1); // StaggeredGridLayoutManager manager=new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL); // recyclerView.setLayoutManager(manager); //3.设置分隔线-默认分隔线 //recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.HORIZONTAL)); // recyclerView.addItemDecoration(new RecyclerViewDivider(this,LinearLayoutManager.VERTICAL)); //2.创建适配器 recycleAdapter = new MyRecylerView(tabDatas, this, new IRecyclerViewClickListener() { @Override public void OnItemClick(View view, String data) { //删除数据 int i = tabDatas.indexOf(data); //从集合中移除数据 tabDatas.remove(i); //适配器刷新 recycleAdapter.notifyItemRangeRemoved(i,1); //添加到推荐列表 tabRecommend.add("+"+data); recommendRecycleAdapter.notifyItemInserted(tabRecommend.size()-1); } }); recyclerView.setAdapter(recycleAdapter); // DragItemCallBack dragItemCallBack=new DragItemCallBack(recyclerView,tabDatas,recycleAdapter); // dragItemCallBack.ad ItemTouchHelper helper=new ItemTouchHelper(new DragItemCallBack(recyclerView,tabDatas,recycleAdapter)); helper.attachToRecyclerView(recyclerView); //添加频道的gridview recommendRecycleAdapter = new MyRecylerView(tabRecommend, this, new IRecyclerViewClickListener() { @Override public void OnItemClick(View view, String data) { //删除数据 int i = tabRecommend.indexOf(data); //从集合中移除数据 tabRecommend.remove(i); //适配器刷新 recommendRecycleAdapter.notifyItemRangeRemoved(i,1); //进行添加 tabDatas.add(data.replace("+","")); recycleAdapter.notifyItemInserted(tabDatas.size()-1); } }); recyclerViewRecommend.setAdapter(recommendRecycleAdapter); } private void initData() { tabDatas.add("新时代"); tabDatas.add("热点"); tabDatas.add("北京"); tabDatas.add("视频"); tabDatas.add("社会"); tabDatas.add("图片"); tabDatas.add("娱乐"); tabDatas.add("问答"); tabDatas.add("科技"); tabRecommend.add("+数码"); tabRecommend.add("+育儿"); tabRecommend.add("+小说"); tabRecommend.add("+热点"); tabRecommend.add("+财经"); tabRecommend.add("+段子"); tabRecommend.add("+直播"); } }
------Mainactivity2布局-----
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="zhanghaijiao.bawei.com.recylerview_demo1.Main2Activity"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/btn" android:text="open" android:layout_gravity="bottom" /> <zhanghaijiao.bawei.com.recylerview_demo1.MyView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/myview" android:visibility="gone" style="@style/dialog_translucent" ></zhanghaijiao.bawei.com.recylerview_demo1.MyView> </FrameLayout>
Main2Activity代码
public class Main2Activity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); Button button=findViewById(R.id.btn); final MyView myView=findViewById(R.id.myview); myView.setCloseListener(new MyView.ICallBacks() { @Override public void closeChannel() { Animation animation = AnimationUtils.loadAnimation(Main2Activity.this, R.anim.translate_close); myView.startAnimation(animation); myView.setVisibility(View.GONE); } }); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { myView.setVisibility(View.VISIBLE); Animation animation = AnimationUtils.loadAnimation(Main2Activity.this, R.anim.translate_open); myView.startAnimation(animation); } }); } }
自定义View代码
public class MyView extends RelativeLayout { private List<String> tabDatas; private List<String> tabRecommend; private MyRecylerView recycleAdapter; private MyRecylerView recommendRecycleAdapter; private RecyclerView recyclerView; private RecyclerView recyclerViewRecommend; private TextView tvClose; private ICallBacks iCallBacks; public MyView(Context context) { super(context); initData(context); } public MyView(Context context, AttributeSet attrs) { super(context, attrs); initData(context); } public MyView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initData(context); } public void setCloseListener(ICallBacks iCallBacks){ this.iCallBacks=iCallBacks; } public void initData(Context context){ //加载布局 LayoutInflater.from(context).inflate(R.layout.channel,this); recyclerView = findViewById(R.id.rev); recyclerViewRecommend = findViewById(R.id.rev_recommend); tvClose = findViewById(R.id.tv_close); tvClose.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { iCallBacks.closeChannel(); } }); initList(); //设置布局适配器-网络、线性、瀑布流 GridLayoutManager manager=new GridLayoutManager(context,3); manager.setOrientation(GridLayoutManager.VERTICAL);//方向设置为横向,spanCount代表行数 recyclerView.setLayoutManager(manager); //布局适配器对象不能重复使用 GridLayoutManager manager1=new GridLayoutManager(context,3); manager.setOrientation(GridLayoutManager.VERTICAL);//方向设置为横向,spanCount代表行数 recyclerViewRecommend.setLayoutManager(manager1); //2.创建数据适配器 recycleAdapter = new MyRecylerView(tabDatas, context, new IRecyclerViewClickListener() { @Override public void OnItemClick(View view, String data) { //删除数据 int i = tabDatas.indexOf(data); //从集合中移除数据 tabDatas.remove(i); //适配器刷新 recycleAdapter.notifyItemRangeRemoved(i,1); //添加到推荐列表 tabRecommend.add("+"+data); recommendRecycleAdapter.notifyItemInserted(tabRecommend.size()-1); } }); recyclerView.setAdapter(recycleAdapter); //实现拖拽 ItemTouchHelper helper=new ItemTouchHelper(new DragItemCallBack(recyclerView,tabDatas,recycleAdapter)); helper.attachToRecyclerView(recyclerView); //添加频道的gridview recommendRecycleAdapter = new MyRecylerView(tabRecommend, context, new IRecyclerViewClickListener() { @Override public void OnItemClick(View view, String data) { //删除数据 int i = tabRecommend.indexOf(data); //从集合中移除数据 tabRecommend.remove(i); //适配器刷新 recommendRecycleAdapter.notifyItemRangeRemoved(i,1); //进行添加 tabDatas.add(data.replace("+","")); recycleAdapter.notifyItemInserted(tabDatas.size()-1); } }); recyclerViewRecommend.setAdapter(recommendRecycleAdapter); } private void initList() { tabDatas=new ArrayList<>(); tabRecommend=new ArrayList<>(); tabDatas.add("新时代"); tabDatas.add("热点"); tabDatas.add("北京"); tabDatas.add("视频"); tabDatas.add("社会"); tabDatas.add("图片"); tabDatas.add("娱乐"); tabDatas.add("问答"); tabDatas.add("科技"); tabRecommend.add("+数码"); tabRecommend.add("+育儿"); tabRecommend.add("+小说"); tabRecommend.add("+热点"); tabRecommend.add("+财经"); tabRecommend.add("+段子"); tabRecommend.add("+直播"); } //定义一个接口 public interface ICallBacks{ void closeChannel(); } }
MyRecylerView代码
/* * 实现三个方法 * 1.onCreateViewHolder 创建视图对象 * 2.onBindViewHolder 绑定视图对象 * 3.getItemCount 得到item的总数 * * 2.为实现点击事件,需要实现OnClickListener接口 * */ public class MyRecylerView extends RecyclerView.Adapter<MyRecylerView.ViewHolder> implements View.OnClickListener{ private List<String> datas; private Context context; private IRecyclerViewClickListener clickListener; public MyRecylerView(List<String> datas, Context context,IRecyclerViewClickListener clickListener) { this.datas = datas; this.context = context; this.clickListener=clickListener; } //根据item的布局,创建ViewHolder对象,被LayoutManager所调用 @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v=View.inflate(context,R.layout.item,null); ViewHolder vh=new ViewHolder(v); //1.设置点击事件 v.setOnClickListener(this); return vh; } //将数据与界面控件进行绑定 @Override public void onBindViewHolder(ViewHolder holder, int position) { holder.tv.setText(datas.get(position)); //存储一下数据 holder.itemView.setTag(datas.get(position)); } @Override public int getItemCount() { return datas.size(); } //点击事件 @Override public void onClick(View view) { //调用接口 clickListener.OnItemClick(view,view.getTag().toString()); } //持有每个item布局页面中所有的元素 class ViewHolder extends RecyclerView.ViewHolder{ private TextView tv; public ViewHolder(View itemView) {//itemView:item的视图对象 super(itemView); tv=itemView.findViewById(R.id.tv); } } }
RecyclerViewDivider代码
public class RecyclerViewDivider extends RecyclerView.ItemDecoration { private Paint mPaint; private Drawable mDivider; private int mDividerHeight = 2;//分割线高度,默认为1px private int mOrientation;//列表的方向:LinearLayoutManager.VERTICAL或LinearLayoutManager.HORIZONTAL private static final int[] ATTRS = new int[]{android.R.attr.listDivider}; /** * 默认分割线:高度为2px,颜色为灰色 * * @param context * @param orientation 列表方向 */ public RecyclerViewDivider(Context context, int orientation) { if (orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL) { throw new IllegalArgumentException("请输入正确的参数!"); } mOrientation = orientation; final TypedArray a = context.obtainStyledAttributes(ATTRS); mDivider = a.getDrawable(0); a.recycle(); } /** * 自定义分割线 * * @param context * @param orientation 列表方向 * @param drawableId 分割线图片 */ public RecyclerViewDivider(Context context, int orientation, int drawableId) { this(context, orientation); mDivider = ContextCompat.getDrawable(context, drawableId); mDividerHeight = mDivider.getIntrinsicHeight(); } /** * 自定义分割线 * * @param context * @param orientation 列表方向 * @param dividerHeight 分割线高度 * @param dividerColor 分割线颜色 */ public RecyclerViewDivider(Context context, int orientation, int dividerHeight, int dividerColor) { this(context, orientation); mDividerHeight = dividerHeight; mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setColor(dividerColor); mPaint.setStyle(Paint.Style.FILL); } //获取分割线尺寸 @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); outRect.set(0, 0, 0, mDividerHeight); } //绘制分割线 @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDraw(c, parent, state); if (mOrientation == LinearLayoutManager.VERTICAL) { drawVertical(c, parent); } else { drawHorizontal(c, parent); } } //绘制横向 item 分割线 private void drawHorizontal(Canvas canvas, RecyclerView parent) { final int left = parent.getPaddingLeft(); final int right = parent.getMeasuredWidth() - parent.getPaddingRight(); final int childSize = parent.getChildCount(); for (int i = 0; i < childSize; i++) { final View child = parent.getChildAt(i); RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams(); final int top = child.getBottom() + layoutParams.bottomMargin; final int bottom = top + mDividerHeight; if (mDivider != null) { mDivider.setBounds(left, top, right, bottom); mDivider.draw(canvas); } if (mPaint != null) { canvas.drawRect(left, top, right, bottom, mPaint); } } } //绘制纵向 item 分割线 private void drawVertical(Canvas canvas, RecyclerView parent) { final int top = parent.getPaddingTop(); final int bottom = parent.getMeasuredHeight() - parent.getPaddingBottom(); final int childSize = parent.getChildCount(); for (int i = 0; i < childSize; i++) { final View child = parent.getChildAt(i); RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams(); final int left = child.getRight() + layoutParams.rightMargin; final int right = left + mDividerHeight; if (mDivider != null) { mDivider.setBounds(left, top, right, bottom); mDivider.draw(canvas); } if (mPaint != null) { canvas.drawRect(left, top, right, bottom, mPaint); } } } }
DragItemCallBack代码
/* * 定义一个类继承自 v7包下的ItemTouchHelper.Callback * 参考https://www.cnblogs.com/wjtaigwh/p/6543354.html * */ public class DragItemCallBack extends ItemTouchHelper.Callback { private RecyclerView recyclerView; private List<String> data; private MyRecylerView adapter; public DragItemCallBack(RecyclerView recyclerView,List<String> data,MyRecylerView adapter) { this.recyclerView = recyclerView; this.data=data; this.adapter=adapter; } //设置是否滑动,以及拖拽的方向 //如果是列表布局,方向是down和up;如果是网格布局,方向是down,up,left,right @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { if(recyclerView.getLayoutManager() instanceof GridLayoutManager){//如果是网格布局 final int dragFlags=ItemTouchHelper.UP|ItemTouchHelper.DOWN|ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT; return makeMovementFlags(dragFlags,0); }else {//列表布局 final int dragFlags=ItemTouchHelper.UP|ItemTouchHelper.DOWN; return makeMovementFlags(dragFlags,0);//swipe:滑动 } } //拖动的时候不断进行回调 @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { //得到当前拖拽ViewHolder的position int fromPosition = viewHolder.getAdapterPosition(); //得到拖拽目标item的position int targetPosition = target.getAdapterPosition(); if(fromPosition<targetPosition){//起始位置小于目标位置,向后移 for (int i = fromPosition; i <targetPosition ; i++) { Collections.swap(data,i,i+1); } }else { for (int i = fromPosition; i < targetPosition; i++) { Collections.swap(data,i,i-1);//向前移,交换位置 } } //通知适配器更新 adapter.notifyItemMoved(fromPosition,targetPosition); return true; } //替换后调用的方法 @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { } //长按选中item的时候调用,高亮显示 @Override public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { super.onSelectedChanged(viewHolder, actionState); if(actionState!=ItemTouchHelper.ACTION_STATE_IDLE){//不等于静止的时候 viewHolder.itemView.setBackgroundColor(Color.LTGRAY); } } //手指松开时还原 @Override public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { super.clearView(recyclerView, viewHolder); viewHolder.itemView.setBackgroundColor(0); } }
IRecyclerViewClickListener自定义接口
/* * 定义一个recyclerView的点击监听接口 */ public interface IRecyclerViewClickListener { /** * 点击事件 * @param view item视图 * @param data 数据 */ void OnItemClick(View view, String data); }
清单文件
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="zhanghaijiao.bawei.com.recylerview_demo1"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> </activity> <activity android:name=".Main2Activity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>