国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android使用RecyclerView實現今日頭條頻道管理功能

2019-10-22 18:31:44
字體:
來源:轉載
供稿:網友

使用過今日頭條的伙計們對這個效果肯定很熟悉。拖拽可排序,點擊標簽后可以刪除。今天我們采用RecyclerView來實現。

Android,今日頭條,頻道管理,RecyclerView

實現思路:

通過ItemTouchHelper來綁定RecyclerView的子控件觸摸事件。
當滑動拖拽的時候,通知適配器來交換兩個子控件的顯示位置。
更改數據源,使數據源與子空間顯示內容一致。
這就是實現的基本思路,是不是很簡單?當然,首先要了解一下ItemTouchHelper這哥們兒是干啥的,有什么作用。

This is a utility class to add swipe to dismiss and drag & drop support to RecyclerView.

It works with a RecyclerView and a Callback class, which configures what type of interactions are enabled and also receives events when user performs these actions.

Depending on which functionality you support, you should override onMove(RecyclerView, ViewHolder, ViewHolder) and / or onSwiped(ViewHolder, int).

This class is designed to work with any LayoutManager but for certain situations, it can be optimized for your custom LayoutManager by extending methods in the ItemTouchHelper.Callback class or implementing ItemTouchHelper.ViewDropHandler interface in your LayoutManager.

By default, ItemTouchHelper moves the items' translateX/Y properties to reposition them. You can customize these behaviors by overriding onChildDraw(Canvas, RecyclerView, ViewHolder, float, float, int, boolean) or onChildDrawOver(Canvas, RecyclerView, ViewHolder, float, float, int, boolean).

Most of the time you only need to override onChildDraw.

通過API文檔的介紹,這個哥們兒是為RecyclerView工作的,他需要一個CallBack,可以回調RecyclerView的子控件滑動和拖拽事件,而且也可以通過這個CallBack重繪我們的子view。這就一目了然了嘛。通過使用ItemTouchHelper,可以很輕松的就實現了RecyclerView觸摸事件的回調。換句話說,只要我們為RecyclerView 綁定了ItemTouchHelper之后,RecyclerView子控件的拖動和滑動事件已經幫我們實現了。我們所要做的就是在觸摸事件之后,如何去改變去更新Adapter和改變我們的數據。

開始擼碼:

public class ChannelActivity extends Activity {  public RecyclerView rv;  public List<DataBean> list = new ArrayList<>();  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_channel);    initData();    initView();  }  private void initView() {    rv = (RecyclerView) findViewById(R.id.rl_view);    rv.setLayoutManager(new GridLayoutManager(this, 4));    MyAdapter adapter = new MyAdapter(this, list);    rv.setAdapter(adapter);    //關聯ItemTouchHelper    ItemTouchHelper touchHelper = new ItemTouchHelper(new MyItemTouchCallBack(adapter));    touchHelper.attachToRecyclerView(rv);  }  private void initData() {    DataBean bean1 = new DataBean("體育", 0, "url");    DataBean bean2 = new DataBean("新聞", 1, "url");    DataBean bean3 = new DataBean("影視", 2, "url");    DataBean bean4 = new DataBean("電視劇", 3, "url");    DataBean bean5 = new DataBean("熱點", 4, "url");    DataBean bean6 = new DataBean("推薦", 5, "url");    DataBean bean7 = new DataBean("屌絲男士", 6, "url");    DataBean bean8 = new DataBean("音樂", 7, "url");    DataBean bean9 = new DataBean("電影", 8, "url");    list.add(bean1);    list.add(bean2);    list.add(bean3);    list.add(bean4);    list.add(bean5);    list.add(bean6);    list.add(bean7);    list.add(bean8);    list.add(bean9);  }}

自定義MyItemTouchCallBack

public class MyItemTouchCallBack extends ItemTouchHelper.Callback {  private TouchInterface touchInterface;  public MyItemTouchCallBack(TouchInterface touchInterface) {    this.touchInterface = touchInterface;  }  @Override  public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {    //拖拽    int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT;    //滑出屏幕    int swipeFlags = ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT | ItemTouchHelper.UP | ItemTouchHelper.DOWN;    return makeMovementFlags(dragFlags, 0);  }  @Override  public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {    int position_target = target.getLayoutPosition();    int position = viewHolder.getLayoutPosition();    //滑動事件回調到了Adapter,用來處理數據    touchInterface.onMove(position, position_target);    return true;  }  //標簽動畫持續時間,默認是250  @Override  public long getAnimationDuration(RecyclerView recyclerView, int animationType, float animateDx, float animateDy) {    return super.getAnimationDuration(recyclerView, animationType, animateDx, animateDy);  }  /**   * 是否可以長按拖拽,默認是true   *   * @return   */  @Override  public boolean isLongPressDragEnabled() {    return super.isLongPressDragEnabled();  }  /**   * 標簽劃出去的回調,direction是滑動的方向   *   * @return   */  @Override  public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {  }}

Adapter類中處理數據

public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> implements TouchInterface {  private Context context;  //是否顯示delete  public boolean isShow;  public List<DataBean> getList() {    return list;  }  public void setList(List<DataBean> list) {    this.list = list;  }  private List<DataBean> list;  public MyAdapter(Context context, List<DataBean> list) {    this.context = context;    this.list = list;  }  @Override  public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {    MyViewHolder viewHolder = new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item_layout, parent, false));    return viewHolder;  }  @Override  public void onBindViewHolder(MyViewHolder holder, final int position) {    holder.tv_des.setText(list.get(position).name);    holder.tv_des.setOnClickListener(new View.OnClickListener() {      @Override      public void onClick(View v) {        DataBean bean = list.remove(position);        notifyDataSetChanged();        Toast.makeText(context,"刪除了"+bean.name+"頻道",Toast.LENGTH_SHORT).show();      }    });    holder.tv_des.setOnLongClickListener(new View.OnLongClickListener() {      @Override      public boolean onLongClick(View v) {        isShow = true;        notifyDataSetChanged();        return true;      }    });    if (isShow) {      holder.iv_icon.setVisibility(View.VISIBLE);    } else {      holder.iv_icon.setVisibility(View.GONE);    }  }  @Override  public int getItemCount() {    return list.size();  }  @Override  public void onMove(int currentPosition, int targetPosition) {    Collections.swap(list, currentPosition, targetPosition);    if (targetPosition < currentPosition) {      List<DataBean> subList = list.subList(targetPosition + 1, currentPosition + 1);      //向右移一位      rightStepList(0, subList);    } else {      List<DataBean> subList = list.subList(currentPosition, targetPosition);      //向左移一位      leftStepList(0, subList);    }    notifyItemMoved(currentPosition, targetPosition);  }}class MyViewHolder extends RecyclerView.ViewHolder {  public ImageView iv_icon;  public TextView tv_des;  public MyViewHolder(View itemView) {    super(itemView);    iv_icon = (ImageView) itemView.findViewById(R.id.iv_icon);    tv_des = (TextView) itemView.findViewById(R.id.tv_des);  }}

解釋一下onMove方法,例如:我們的數據是[1,2,3,4,5,6],當6移動到3的位置時,那么數據源最后變化為[1,2,6,3,4,5]。但是在顯示的時候我們先是將當前position和targetposition對調[1,2,6,4,5,3],然后取出[4,5,3]進行右移一位,這樣數據源就對上了。如果是從3移動到6進行左移就可以了,數據排序的算法,采用反轉的思想。

public class DataUtils {  /**   * 利用反轉的思想對數據進行排序   * 例如:list{0,1,2,3,4,5,6,7} 左移一位   * 第一步:第一位先反轉{0,1,2,3,4,5,6,7}   * 第二部:剩下的在反轉{0,7,6,5,4,3,2,1}   * 第三步:全部反轉{1,2,3,4,5,6,7,0}   *   * 例如:list{0,1,2,3,4,5,6,7} 右移一位   * 第一步:最右邊一位先反轉{1,2,3,4,5,6,7}   * 第二部:剩下的在反轉{6,5,4,3,2,1,0,7}   * 第三步:全部反轉{7,6,5,4,3,2,1,0}   *   * 因為list的index是從0開始的,step要相應的-1   * 優點:少創建對象,優化內存   *   * @param start   * @param end   * @param list   */  public static void reverseList(int start,int end,List list){    int count = (end+1-start)/2 ;    for(int i = 0;i< count;i++){      Object temp = list.get(start+i);      list.set(start+i,list.get(end-i));      list.set(end-i,temp);    }  }  public static void leftStepList(int step,List list){    int size = list.size() -1;    //左移    reverseList(0,step,list);    reverseList(step+1,size,list);    reverseList(0,size,list);  }  public static void rightStepList(int step,List list){    int size = list.size() -1;    //右移    reverseList(size-step,size,list);    reverseList(0,size-step-1,list);    reverseList(0,size,list);  }}

Activity布局文件:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  xmlns:tools="http://schemas.android.com/tools"  android:id="@+id/activity_channel"  android:layout_width="match_parent"  android:layout_height="match_parent"  tools:context="com.iwintrue.channe.ChannelActivity">  <android.support.v7.widget.RecyclerView    android:id="@+id/rl_view"    android:background="@color/white"    android:layout_width="match_parent"    android:layout_height="match_parent"></android.support.v7.widget.RecyclerView></RelativeLayout>

子控件布局文件:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:orientation="vertical"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  >  <RelativeLayout    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:padding="10dp">    <TextView      android:id="@+id/tv_des"      android:layout_width="80dp"      android:layout_height="30dp"      android:text="屌絲男士"      android:gravity="center"      android:background="@drawable/rl_shape"      android:textColor="@color/textColor"      android:layout_marginTop="5dp"      android:layout_marginRight="5dp" />    <ImageView      android:layout_alignRight="@+id/tv_des"      android:layout_marginRight="-5dp"      android:id="@+id/iv_icon"      android:layout_width="20dp"      android:layout_height="20dp"      android:src="@mipmap/delete"      android:scaleType="fitXY"      android:visibility="gone" />  </RelativeLayout></LinearLayout>

實現效果:

Android,今日頭條,頻道管理,RecyclerView

github地址:https://github.com/zhoukai1526/Channel

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 霸州市| 项城市| 台南市| 南丰县| 来安县| 治多县| 奉化市| 玉屏| 河南省| 南昌市| 成都市| 淮北市| 伊通| 时尚| 旺苍县| 金平| 拜城县| 剑川县| 松江区| 北辰区| 五大连池市| 宝丰县| 旬阳县| 瓦房店市| 泸州市| 香格里拉县| 云南省| 朝阳市| 苍溪县| 雷山县| 新绛县| 蒙阴县| 鞍山市| 格尔木市| 奇台县| 宁国市| 滦平县| 宜良县| 汝州市| 怀化市| 潢川县|