Android RecyclerView 상세 설명 및 슬라이딩 삭제 등

본문 RecyclerView Demo
RecyclerView 세 가지 자체 레이아웃
본문 사진 인 터 페 이 스 는 건어물 수용소 에서 나온다.http://gank.io/api
RecyclerView 는 슈퍼 port. v7 패키지 의 컨트롤 로 ListView 와 GridView 의 증강 업그레이드 버 전이 라 고 할 수 있 습 니 다.
RecyclerView 에 대한 공식 설명 은 (번역 을 하지 않 는 것 은 내 가 영 어 를 못 해서 가 아니 라 정말):
A flexible view for providing a limited window into a large data set.
리 클 러 뷰 는 2014 년 발 표 된 지 오래 돼 사용 이 보편화 됐다.
본 고 는 주로 RecyclerView 의 기초 사용, 더 많은 데 이 터 를 자동 으로 불 러 오고 item 의 드래그 와 스 크 래 치 삭 제 를 소개 한다.자세 한 효과 와 사용 은 제 demo 를 보십시오.
RecyclerView 기초 용법
RecyclerView 의 용법 은 ListView 와 유사 하 다.나 는 격자 구 조 를 예 로 들 어 코드 를 먼저 올 리 고 다시 자세하게 말 했다.
우선 레이아웃 에서 이 컨트롤 을 만 듭 니 다:
    
 



    





    
    


Activity 의 코드 는 다음 과 같 습 니 다.
public class GridActivity extends AppCompatActivity {

private static RecyclerView recyclerview;
private CoordinatorLayout coordinatorLayout;
private GridAdapter mAdapter;
private List meizis;
private GridLayoutManager mLayoutManager;
private int lastVisibleItem ;
private int page=1;
private ItemTouchHelper itemTouchHelper;
private SwipeRefreshLayout swipeRefreshLayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_grid);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    initView();//     
    setListener();//      

    //      
    new GetData().execute("http://gank.io/api/data/  /10/1");

}

private void initView(){
    coordinatorLayout=(CoordinatorLayout)findViewById(R.id.grid_coordinatorLayout);

    recyclerview=(RecyclerView)findViewById(R.id.grid_recycler);
    mLayoutManager=new GridLayoutManager(GridActivity.this,3,GridLayoutManager.VERTICAL,false);//     3        
    recyclerview.setLayoutManager(mLayoutManager);

    swipeRefreshLayout=(SwipeRefreshLayout) findViewById(R.id.grid_swipe_refresh) ;
    //  SwipeRefreshLayout   
    swipeRefreshLayout.setProgressViewOffset(false, 0,  (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, getResources().getDisplayMetrics()));
}

private void setListener(){
    //swipeRefreshLayout    
    swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            page=1;
            new GetData().execute("http://gank.io/api/data/  /10/1");
        }
    });
    }


private class GetData extends AsyncTask {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        //  swipeRefreshLayout     
        swipeRefreshLayout.setRefreshing(true);
    }

    @Override
    protected String doInBackground(String... params) {

        return MyOkhttp.get(params[0]);
    }

    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        if(!TextUtils.isEmpty(result)){

            JSONObject jsonObject;
            Gson gson=new Gson();
            String jsonData=null;

            try {
                jsonObject = new JSONObject(result);
                jsonData = jsonObject.getString("results");
            } catch (JSONException e) {
                e.printStackTrace();
            }
            if(meizis==null||meizis.size()==0){
                meizis= gson.fromJson(jsonData, new TypeToken>() {}.getType());

                Meizi pages=new Meizi();
                pages.setPage(page);
                meizis.add(pages);//                 item
            }else{
                List  more= gson.fromJson(jsonData, new TypeToken>() {}.getType());
                meizis.addAll(more);

                Meizi pages=new Meizi();
                pages.setPage(page);
                meizis.add(pages);//                 item
            }

            if(mAdapter==null){
                recyclerview.setAdapter(mAdapter = new GridAdapter(GridActivity.this,meizis));//recyclerview     

                //             
                mAdapter.setOnItemClickListener(new GridAdapter.OnRecyclerViewItemClickListener() {
                    @Override
                    public void onItemClick(View view) {
                        int position=recyclerview.getChildAdapterPosition(view);
                        SnackbarUtil.ShortSnackbar(coordinatorLayout,"   "+position+" ",SnackbarUtil.Info).show();
                       //  Snackbar   ,        《      ,   Snackbar!——Android Snackbar      》http://www.jianshu.com/p/cd1e80e64311
                    }
                    @Override
                    public void onItemLongClick(View view) {

                    }
                });       
            }else{
                //        
                mAdapter.notifyDataSetChanged();
            }
        }
        //  swipeRefreshLayout    
        swipeRefreshLayout.setRefreshing(false);
    }
}
}

다음은 RecyclerView 어댑터 를 보 겠 습 니 다.
public  class GridAdapter extends RecyclerView.Adapter implements View.OnClickListener, View.OnLongClickListener {

private Context mContext;
private List datas;//  

//       
public static interface OnRecyclerViewItemClickListener {
    void onItemClick(View view);
    void onItemLongClick(View view);
}
private OnRecyclerViewItemClickListener mOnItemClickListener = null;
public void setOnItemClickListener(OnRecyclerViewItemClickListener listener) {
    mOnItemClickListener = listener;
}

//      
public GridAdapter(Context context,List datas) {
    mContext=context;
    this.datas=datas;
}

@Override
public int getItemViewType(int position) {
    //  item  ,        (   URL)
    if (!TextUtils.isEmpty(datas.get(position).getUrl())) {
        return 0;
    } else {
        return 1;
    }
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
    //  item      ViewHolder
    if(viewType==0){
        View view = LayoutInflater.from(mContext
                ).inflate(R.layout.grid_meizi_item, parent,
                false);//        imageview      
        MyViewHolder holder = new MyViewHolder(view);

       //             
        view.setOnClickListener(this);
        view.setOnLongClickListener(this);

        return holder;
    }else{
        MyViewHolder2 holder2=new MyViewHolder2(LayoutInflater.from(
                mContext).inflate(R.layout.page_item, parent,
                false));//        textview      
        return holder2;
    }

}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
 //    item      ,   MyViewHolder       ,   MyViewHolder2     
    if(holder instanceof MyViewHolder){
        Picasso.with(mContext).load(datas.get(position).getUrl()).into(((MyViewHolder) holder).iv);//      
    }else if(holder instanceof MyViewHolder2){
        ((MyViewHolder2) holder).tv.setText(datas.get(position).getPage()+" ");
    }

}

@Override
public int getItemCount()
{
    return datas.size();//       
}

//      
@Override
public void onClick(View v) {
    if (mOnItemClickListener != null) {
        mOnItemClickListener.onItemClick(v);
    }
}
@Override
public boolean onLongClick(View v) {
    if (mOnItemClickListener!= null) {
      mOnItemClickListener.onItemLongClick(v);
   }
    return false;
}

//   ViewHolder,      
class MyViewHolder extends RecyclerView.ViewHolder
{
    private ImageButton iv;

    public MyViewHolder(View view)
    {
        super(view);
        iv = (ImageButton) view.findViewById(R.id.iv);
    }
}
//   ViewHolder,      
class MyViewHolder2 extends RecyclerView.ViewHolder
{
    private TextView tv;

    public MyViewHolder2(View view)
    {
        super(view);
        tv = (TextView) view.findViewById(R.id.tv);
    }
}

    //    item
    public void addItem(Meizi meizi, int position) {
        meizis.add(position, meizi);
        notifyItemInserted(position);
        recyclerview.scrollToPosition(position);//recyclerview     item 
    }

    //    item
    public void removeItem(final int position) {
        meizis.remove(position);
        notifyItemRemoved(position);
    }
}

데이터 클래스:
 public class Meizi {

private String url;//    
private int page;//  

public String getUrl() {
    return url;
}

public void setUrl(String url) {
    this.url = url;
}

public int getPage() {
    return page;
}

public void setPage(int page) {
    this.page = page;
}  
}

RecyclerView 의 사용 은 ListView 와 비슷 하 죠?
RecyclerView 는 setLayoutManager () 방법 으로 레이아웃 관리 자 를 설정 해 야 합 니 다. RecyclerView 는 세 개의 기본 레이아웃 관리자 인 LinearLayoutManager, GridLayoutManager, Staggered GridLayoutManager 가 있 는데 모두 가로 와 세로 배열, 역방향 미끄럼 을 지원 합 니 다.RecyclerView 를 가로 슬라이딩 으로 바 꾸 려 면 호출 을 통 해서 도 가능 합 니 다.
mLayoutManager.setOrientation(GridLayoutManager.HORIZONTAL);

RecyclerView 는 ListView 처럼 item 의 클릭 감청 을 제공 하지 않 기 때문에 우 리 는 스스로 실현 할 수 밖 에 없다.RecyclerView 의 item 클릭 이벤트 감청 은 본 논문 에서 item 의 view 에 감청 을 설정 할 수도 있 고 recyclerView. addOnitem Touch Listener 에서 제스처 를 판단 하여 실현 할 수도 있 습 니 다.
다음 방법 으로 item 로 딩 이나 제거 할 때 애니메이션 을 설정 할 수 있 습 니 다.
recyclerView.setItemAnimator(new DefaultItemAnimator());

더 많은 애니메이션 효 과 는 다른 사람 이 쓴 RecyclerView ItemAnimators 를 볼 수 있 습 니 다. 이 항목.
자동 으로 더 많이 불 러 오기
목록 어 딘 가 에 미 끄 러 지 려 면 다음 페이지 를 자동 으로 불 러 옵 니 다 (예 를 들 어 마지막 두 아 이 템 이 남 았 을 때). RecyclerView 에 미 끄 러 지 는 감청 을 설정 하여 현재 표 시 된 마지막 아 이 템 이 어댑터 에 있 는 위 치 를 가 져 올 수 있 습 니 다. 이 아 이 템 의 위치 가 어댑터 아 이 템 의 총 갯 수 를 2 로 줄 이거 나 같 으 면 다음 페이지 의 데 이 터 를 불 러 옵 니 다.GridLayoutManager 와 LinearLayoutManager 의 방법 은 다음 과 같다.
  //recyclerview    
    recyclerview.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
            //0:        ;1 :                      ;2 :      ,          ;
            //               item ,       
            if (newState == RecyclerView.SCROLL_STATE_IDLE
                    && lastVisibleItem +2>=mLayoutManager.getItemCount()) {
                new GetData().execute("http://gank.io/api/data/  /10/"+(++page));
            }
        }

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            //                    。
            lastVisibleItem = mLayoutManager.findLastVisibleItemPosition();
        }
    });

Staggered Grid LayoutManager 는 item 의 위치 가 교차 되 어 있 기 때문에 find Last Visible ItemPosition () 방법 은 하나의 배열 로 되 돌아 가기 때문에 이 배열 의 최대 치 를 먼저 판단 해 야 합 니 다. 위의 onScrolled 방법 은 이렇게 쓰 여 있 습 니 다.
    int[] positions= mLayoutManager.findLastVisibleItemPositions(null);
    lastVisibleItem =Math.max(positions[0],positions[1]);//  StaggeredGridLayoutManager       

다음 페이지 를 자동 으로 불 러 옵 니 다. gif
XRecyclerView 는 다른 사람 이 쓴 라 이브 러 리 로 RecyclerView 의 드 롭 다운 헤드 와 아래쪽 로드 레이아웃 을 실현 하고 필요 한 것 은 볼 수 있 습 니 다.
Item 드래그 앤 드 롭 다운 삭제
ItemTouchHelper 는 RecyclerView 의 미끄럼 삭제 와 드래그 를 처리 하 는 보조 클래스 로 RecyclerView 의 item 드래그 이동 과 미끄럼 삭 제 는 이 를 통 해 이 루어 집 니 다.
ItemTouchHelper 의 감청 은 다음 과 같다.
    itemTouchHelper=new ItemTouchHelper(new ItemTouchHelper.Callback() {

        //            
        @Override
        public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
            int dragFlags=0,swipeFlags=0;
            if(recyclerView.getLayoutManager() instanceof StaggeredGridLayoutManager||recyclerView.getLayoutManager() instanceof GridLayoutManager){
               //      4   
               dragFlags=ItemTouchHelper.UP|ItemTouchHelper.DOWN|ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT;
            }else if(recyclerView.getLayoutManager() instanceof LinearLayoutManager){
               //      2   
               dragFlags=ItemTouchHelper.UP|ItemTouchHelper.DOWN;

               swipeFlags = ItemTouchHelper.START|ItemTouchHelper.END; //               
            }
            return makeMovementFlags(dragFlags,swipeFlags);//swipeFlags  0  item   
        }

        //  item          
        @Override
        public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
            int from=viewHolder.getAdapterPosition();
            int to=target.getAdapterPosition();

            Meizi moveItem=meizis.get(from);
            meizis.remove(from);
            meizis.add(to,moveItem);//            

            mAdapter.notifyItemMoved(from,to);//      item   
            return true;
        }

        @Override
        public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        //        
        }

        @Override
        public boolean isLongPressDragEnabled() {
            return false;//  true    item       
        }
    });

itemTouchHelper 는 recyclerView 와 연결 해 야 효과 가 있 습 니 다. recyclerView 가 초기 화 될 때 호출 합 니 다.
     itemTouchHelper.attachToRecyclerView(recyclerview);

격자 레이아웃 에 있 는 그림 아 이 템 을 끌 수 있 고 페이지 아 이 템 을 끌 수 없 기 때문에 저 는 isLongPress Drag Enabled () 방법 으로 돌아 온 false 이 고 아 이 템 의 긴 클릭 이벤트 감청 에서 구체 적 으로 처리 합 니 다.
       mAdapter.setOnItemClickListener(new GridAdapter.OnRecyclerViewItemClickListener() {
       @Override
       public void onItemClick(View view) {
       }

        @Override
        public void onItemLongClick(View view) {
              itemTouchHelper.startDrag(recyclerview.getChildViewHolder(view));//    item
           }
       });

아 이 템 을 끌 고 미 끄 러 질 때의 응답 애니메이션 효 과 를 설정 하려 면 아 이 템 터치 헬 퍼 의 다음 세 가지 방법 을 사용 할 수 있 습 니 다.선형 레이아웃 예제:
// item       
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
super.onSelectedChanged(viewHolder, actionState);
 if(actionState==ItemTouchHelper.ACTION_STATE_DRAG){
       viewHolder.itemView.setBackgroundColor(Color.LTGRAY);//           
    }
}

// item       
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
 viewHolder.itemView.setBackgroundColor(Color.WHITE);//             
}

 // item       
 @Override
 public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
 super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
  //  item        item   。screenwidth           
  viewHolder.itemView.setAlpha(1-Math.abs(dX)/screenwidth);
 }

드래그 앤 드 롭 삭제. gif
본문 RecyclerView Demo

좋은 웹페이지 즐겨찾기