前言
仿今日头条频道选择页
1、效果
2、工程文件目录
3、具体实现
ItemDragHelperCallback.java
package com.komling.itemtouchdemo;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.support.v7.widget.helper.ItemTouchHelper;
/**
* Created by 梧桐树 on 2017/11/28.
*/
public class ItemDragHelperCallback extends ItemTouchHelper.Callback {
/**
* 指定可以支持的拖放和滑动的方向
* 这里我们启用了上下左右两种方向。注:上下为拖动(drag),左右为滑动(swipe)
*
* @param recyclerView
* @param viewHolder
* @return
*/
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
int dragFlags;
RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
if (manager instanceof GridLayoutManager || manager instanceof StaggeredGridLayoutManager) {
dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
} else {
dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
}
//如果想支持滑动(删除)操作,swipeFlags = ItemTouchHelper.START|ItemTouchHelper.END
int swipeFlags = 0;
//使用helperItemTouchHelper.makeMovementFlags(int, int)来构造返回的flag
return makeMovementFlags(dragFlags, swipeFlags);
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
if (viewHolder.getItemViewType() != target.getItemViewType()) {
return false;
}
if (recyclerView.getAdapter() instanceof IOnItemMoveListener) {
IOnItemMoveListener listener = (IOnItemMoveListener) recyclerView.getAdapter();
listener.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
}
return true;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
}
@Override
public boolean isLongPressDragEnabled() {
return false;
}
@Override
public boolean isItemViewSwipeEnabled() {
return false;
}
}
RecyclerListAdapter.xml
package com.komling.itemtouchdemo;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.Collections;
import java.util.List;
/**
* Created by 梧桐树 on 2017/11/28.
*/
public class RecyclerListAdapter extends RecyclerView.Adapter implements IOnItemMoveListener {
//我的频道 标题部分
public static final int TYPE_MY_CHANNEL_HEADER = 0;
//我的频道
public static final int TYPE_MY_CHANNEL = 1;
//其他频道 标题部分
public static final int TYPE_OTHER_CHANNEL_HEADER = 2;
//其他频道
public static final int TYPE_OTHER_CHANNEL = 3;
//我的频道之前header的数量
private static final int COUNT_PRE_MY_HEADER = 1;
//其他频道之前的header的数量
private static final int COUNT_PRE_OTHER_HEADER = COUNT_PRE_MY_HEADER + 1;
private Context context;
private ItemTouchHelper itemTouchHelper;
private List<String> mMyChannel, mOtherChannel;
private boolean isEditMode = false;
public RecyclerListAdapter(Context context, ItemTouchHelper helper, List<String> mMyChannel, List<String> mOtherChannel) {
this.context = context;
this.itemTouchHelper = helper;
this.mMyChannel = mMyChannel;
this.mOtherChannel = mOtherChannel;
}
@Override
public int getItemViewType(int position) {
if (position == 0) {//我的频道标题部分
return TYPE_MY_CHANNEL_HEADER;
} else if (position > 0 && position < mMyChannel.size() + COUNT_PRE_MY_HEADER) {//我的频道
return TYPE_MY_CHANNEL;
} else if (position == mMyChannel.size() + COUNT_PRE_MY_HEADER) {//其他频道标题部分
return TYPE_OTHER_CHANNEL_HEADER;
} else {//其他频道
return TYPE_OTHER_CHANNEL;
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
final View view;
switch (viewType) {
case TYPE_MY_CHANNEL_HEADER:
view = LayoutInflater.from(context).inflate(R.layout.item_channel_my_header, parent, false);
final MyChannelHeaderViewHolder holder = new MyChannelHeaderViewHolder(view);
holder.mTvBtnEdit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!isEditMode) {
startEditMode((RecyclerView) parent);
holder.mTvBtnEdit.setText("完成");
} else {
cancelEditMode((RecyclerView) parent);
holder.mTvBtnEdit.setText("编辑");
}
}
});
return holder;
case TYPE_MY_CHANNEL:
view = LayoutInflater.from(context).inflate(R.layout.item_channel_my, parent, false);
final MyChannelViewHolder myHolder = new MyChannelViewHolder(view);
myHolder.mTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (isEditMode) {
moveMyToOther(myHolder);
} else {
Toast.makeText(context, mMyChannel.get(myHolder.getAdapterPosition() - COUNT_PRE_MY_HEADER), Toast.LENGTH_LONG).show();
}
}
});
myHolder.mTextView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (!isEditMode) {
RecyclerView recyclerView = (RecyclerView) parent;
startEditMode(recyclerView);
View view = parent.getChildAt(0);
TextView mTvBtnEdit = view.findViewById(R.id.tv_btn_edit);
if (mTvBtnEdit != null) {
mTvBtnEdit.setText("完成");
}
}
itemTouchHelper.startDrag(myHolder);
return true;
}
});
return myHolder;
case TYPE_OTHER_CHANNEL_HEADER:
view = LayoutInflater.from(context).inflate(R.layout.item_channel_other_header, parent, false);
return new RecyclerView.ViewHolder(view) {
};
case TYPE_OTHER_CHANNEL:
view = LayoutInflater.from(context).inflate(R.layout.item_channel_other, parent, false);
final OtherChannelViewHolder otherHolder = new OtherChannelViewHolder(view);
otherHolder.mTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
moveOtehrToMy(otherHolder);
}
});
return otherHolder;
}
return null;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof MyChannelViewHolder) {
MyChannelViewHolder myHolder = (MyChannelViewHolder) holder;
myHolder.mTextView.setText(mMyChannel.get(position - COUNT_PRE_MY_HEADER));
if (isEditMode) {
myHolder.mImgDel.setVisibility(View.VISIBLE);
} else {
myHolder.mImgDel.setVisibility(View.GONE);
}
} else if (holder instanceof OtherChannelViewHolder) {
OtherChannelViewHolder otherHolder = (OtherChannelViewHolder) holder;
otherHolder.mTextView.setText(mOtherChannel.get(position - mMyChannel.size() - COUNT_PRE_OTHER_HEADER));
}
}
@Override
public int getItemCount() {
return mMyChannel.size() + mOtherChannel.size() + COUNT_PRE_OTHER_HEADER;
}
@Override
public void onItemMove(int fromPosition, int toPosition) {
// 用于交换在指定列表中的指定位置的元素。
Collections.swap(mMyChannel, fromPosition, toPosition);
notifyItemMoved(fromPosition, toPosition);
}
/**
* 开启编辑模式
*
* @param parent
*/
public void startEditMode(RecyclerView parent) {
isEditMode = true;
int visibleChildCount = parent.getChildCount();
if (mMyChannel.size() <= visibleChildCount - COUNT_PRE_OTHER_HEADER) {
for (int i = 0; i < mMyChannel.size() + COUNT_PRE_MY_HEADER; i++) {
View view = parent.getChildAt(i);
ImageView imgEdit = view.findViewById(R.id.img_del);
if (imgEdit != null) {
imgEdit.setVisibility(View.VISIBLE);
}
}
}
}
/**
* 取消编辑模式
*
* @param parent
*/
public void cancelEditMode(RecyclerView parent) {
isEditMode = false;
int visibleChildCount = parent.getChildCount();
if (mMyChannel.size() <= visibleChildCount - COUNT_PRE_OTHER_HEADER) {
for (int i = 0; i < mMyChannel.size() + COUNT_PRE_MY_HEADER; i++) {
View view = parent.getChildAt(i);
ImageView imgEdit = view.findViewById(R.id.img_del);
if (imgEdit != null) {
imgEdit.setVisibility(View.INVISIBLE);
}
}
}
}
/**
* 我的频道移动到 其他频道
*
* @param myHolder
*/
private void moveMyToOther(MyChannelViewHolder myHolder) {
int position = myHolder.getAdapterPosition();
int startPosition = position - COUNT_PRE_MY_HEADER;
if (startPosition > mMyChannel.size() - 1) {
return;
}
String str = mMyChannel.get(startPosition);
mMyChannel.remove(startPosition);
mOtherChannel.add(0, str);
notifyItemMoved(position, mMyChannel.size() + COUNT_PRE_OTHER_HEADER);
}
/**
* 其他频道移动到 我的频道
*
* @param otherHolder
*/
private void moveOtehrToMy(OtherChannelViewHolder otherHolder) {
int position = processItemRemoveAdd(otherHolder);
if (position == -1) {
return;
}
notifyItemMoved(position, mMyChannel.size() - 1 + COUNT_PRE_MY_HEADER);
}
private int processItemRemoveAdd(OtherChannelViewHolder otherHolder) {
int position = otherHolder.getAdapterPosition();
int startPosition = position - mMyChannel.size() - COUNT_PRE_OTHER_HEADER;
if (startPosition > mOtherChannel.size() - 1) {
return -1;
}
String str = mOtherChannel.get(startPosition);
mOtherChannel.remove(startPosition);
mMyChannel.add(str);
return position;
}
//我的频道标题
static class MyChannelHeaderViewHolder extends RecyclerView.ViewHolder {
TextView mTvBtnEdit;
public MyChannelHeaderViewHolder(View itemView) {
super(itemView);
mTvBtnEdit = itemView.findViewById(R.id.tv_btn_edit);
}
}
//我的频道
static class MyChannelViewHolder extends RecyclerView.ViewHolder {
TextView mTextView;
ImageView mImgDel;
public MyChannelViewHolder(View itemView) {
super(itemView);
mTextView = itemView.findViewById(R.id.textView);
mImgDel = itemView.findViewById(R.id.img_del);
}
}
//其他频道
static class OtherChannelViewHolder extends RecyclerView.ViewHolder {
TextView mTextView;
ImageView mImgDel;
public OtherChannelViewHolder(View itemView) {
super(itemView);
mTextView = itemView.findViewById(R.id.textView);
mImgDel = itemView.findViewById(R.id.img_del);
}
}
}
项目下载地址:http://download.csdn.net/download/ghsfggdsfgdsf/10138808