添加某界面的动态(RecycleView)
效果如下,滑动删除
由于我们之前已经完成了布局,一个整体的这样的一个框架,所以我们这次做的时候需要改动的就只有其中一个fragment,而不需要去调节整个mainactivity,在理清楚逻辑之后,咱们可以开始修改/添加了。这里我就来说一下滑动删除怎样来写吧!
1、添加布局文件
因为之前我们已经做了四个tab,显示了textview的内容,而这次我们要使用recycleview来创建列表,所以我们就可以修改其中的一个,如下:
这里的话就很简单的添加一个recycleview就行了,然后设置一下各种参数,id,layout_width,layout_height等等,我就不多说了,添加了布局之后,我们就需要去调用它
2、获取对象句柄,将其连接到布局管理器,并为要显示的数据附加适配器,首先来看activity的内容
public class weixinFragmentextends Fragment {
Viewview;
SwipeAdapteradapter;
RecyclerViewrcvSwipe;
private final ListmList =new ArrayList<>();
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
private void initData() {
mList.add("亚特兰大老鹰");
mList.add("夏洛特黄蜂");
mList.add("迈阿密热火");
mList.add("奥兰多魔术");
mList.add("华盛顿奇才");
mList.add("波士顿凯尔特人");
mList.add("布鲁克林篮网");
mList.add("纽约尼克斯");
mList.add("费城76人");
mList.add("多伦多猛龙");
mList.add("芝加哥公牛");
mList.add("克里夫兰骑士");
mList.add("底特律活塞");
mList.add("印第安纳步行者");
mList.add("密尔沃基雄鹿");
mList.add("达拉斯独行侠");
mList.add("休斯顿火箭");
mList.add("孟菲斯灰熊");
mList.add("新奥尔良鹈鹕");
mList.add("圣安东尼奥马刺");
mList.add("丹佛掘金");
mList.add("明尼苏达森林狼");
mList.add("俄克拉荷马城雷霆");
mList.add("波特兰开拓者");
mList.add("犹他爵士");
mList.add("金州勇士");
mList.add("洛杉矶快船");
mList.add("洛杉矶湖人");
mList.add("菲尼克斯太阳");
mList.add("萨克拉门托国王");
}
private void initView() {
adapter =new SwipeAdapter(getActivity());
rcvSwipe =view.findViewById(R.id.rcv_swipe);
rcvSwipe.setLayoutManager(new LinearLayoutManager(getActivity()));
rcvSwipe.setHasFixedSize(true);
rcvSwipe.setAdapter(adapter);
adapter.setSwipeDataList(mList);
ItemTouchHelper.Callback callback =new SwipeItemTouchHelper(adapter);
ItemTouchHelper touchHelper =new ItemTouchHelper(callback);
touchHelper.attachToRecyclerView(rcvSwipe);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.tab01, container,false);
initView();
initData();
return view;
}
}
具体的写法其实都差不多,官网里有固定的写法,这里我就说一下传参的问题,因为之前传参的原因导致出了很多问题,像最后一个view,本来是我自己定义一个,开始是空值,后来才发现,然后就将return 啥的改成了view,之前我也不知道是啥,然后还有就是调用initData和initView,不能放错位置
3、添加列表适配器
要将所有数据输入列表中,您必须扩展 RecyclerView.Adapter 类。此对象会创建项的视图,并在原始项不再可见时用新数据项替换部分视图的内容。下面是我的adapter的例子,实际上结构大体差不多,在下面的方法中不同的动画有不同的写法,所以修改起来很容易
public class SwipeAdapterextends RecyclerView.Adapterimplements ItemTouchHelperListener {
private final ContextmContext;
private ListmList =new ArrayList<>();
public SwipeAdapter(Context context) {
mContext = context;
}
public void setSwipeDataList(List list) {
mList = list;
notifyDataSetChanged();
}
@NonNull
@Override
public SwipeViewHolder onCreateViewHolder(@NonNull ViewGroup parent,int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.swipe_recycle_item, parent,false);
return new SwipeViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull SwipeViewHolder holder,int position) {
holder.tvContent.setText(mList.get(position));
}
@Override
public int getItemCount() {
return mList ==null ?0 :mList.size();
}
@Override
public void onItemDismiss(int position) {
if (position <0 || position > getItemCount()) {
return;
}
mList.remove(position);
notifyItemRemoved(position);
// 解决 RecyclerView 删除 Item 导致位置错乱的问题
if (position !=mList.size()) {
notifyItemRangeChanged(position,mList.size() - position);
}
}
public static class SwipeViewHolderextends RecyclerView.ViewHolder {
TextViewtvContent;
public SwipeViewHolder(View itemView) {
super(itemView);
tvContent = itemView.findViewById(R.id.tv_content);
}
}
}
每当某项内容发生变化时,RecyclerView 会使用 animator 来更改其外观。该 animator 是扩展抽象 RecyclerView.ItemAnimator 类的对象。默认情况下,RecyclerView 使用 DefaultItemAnimator 来提供动画。如果您想提供自定义动画,可以通过扩展 RecyclerView.ItemAnimator 来定义自己的 animator 对象。如下,这只是我的这个动画的写法,想要不同的动画都可以,看你自己想怎么写
public class SwipeItemTouchHelperextends ItemTouchHelper.Callback {
private final SwipeAdaptermAdapter;
public SwipeItemTouchHelper(SwipeAdapter adapter) {
mAdapter = adapter;
}
/**
* 设置滑动类型标记
*/
@Override
public int getMovementFlags(@NotNull RecyclerView recyclerView, RecyclerView.@NotNull ViewHolder viewHolder) {
int dragFlags =0;// 禁止上下拖动
int swipeFlags = ItemTouchHelper.LEFT;// 只允许从右向左滑动
return makeMovementFlags(dragFlags, swipeFlags);
}
@Override
public boolean onMove(@NotNull RecyclerView recyclerView, RecyclerView.@NotNull ViewHolder viewHolder, RecyclerView.@NotNull ViewHolder target) {
return false;
}
/**
* 滑动删除 Item 的操作
*/
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder,int direction) {
mAdapter.onItemDismiss(viewHolder.getAdapterPosition());
}
/**
* 设置 Item 不支持长按拖动
*/
@Override
public boolean isLongPressDragEnabled() {
return false;
}
/**
* 设置 Item 支持滑动
*/
@Override
public boolean isItemViewSwipeEnabled() {
return true;
}
/**
* Item 被选中时候,改变 Item 的背景
*/
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder,int actionState) {
// item 被选中的操作
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
viewHolder.itemView.setBackgroundResource(R.drawable.select_bg);
}
super.onSelectedChanged(viewHolder, actionState);
}
/**
* 移动过程中重新绘制 Item,随着滑动的距离,设置 Item 的透明度
*/
@Override
public void onChildDraw(@NotNull Canvas c,@NotNull RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,float dX,float dY,int actionState,boolean isCurrentlyActive) {
float x = Math.abs(dX) +0.5f;
float width = viewHolder.itemView.getWidth();
float alpha =1f - x / width;
viewHolder.itemView.setAlpha(alpha);
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
/**
* 用户操作完毕或者动画完毕后调用,恢复 item 的背景和透明度
*/
@Override
public void clearView(@NotNull RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
// 操作完毕后恢复颜色
viewHolder.itemView.setBackgroundResource(R.drawable.common_bg);
viewHolder.itemView.setAlpha(1.0f);
super.clearView(recyclerView, viewHolder);
}
}
这里就是自定义的动画,实际上我们将中间的禁止上下滑动和只允许从右往左滑动可以改为上下左右都可以滑动,也比较简单。最后我们需要一个监听程序
public interface ItemTouchHelperListener {
void onItemDismiss(int position);
}
因为我们点击是系统要识别,就跟之前的点击页面可以切换是一样的,所以我也就不多说了,具体项目可以参见https://gitee.com/guan-zhiwei/three-interfaces-of-wechat.git,感谢阅读1