RecyclerView詳細介紹-----解決點選事件,重新整理錯誤(二)
1. 前言
RecyclerView 沒有提供類似ListView的setOnItemClickListener方法,所以只有我們自己為RecyclerView新增點選事件, 本篇文章主要介紹如何新增點選事件,進行Item增加和刪除,並且解決RecycleView Adapter使用notifyItemRemoved和notifyItemInserted造成Position混亂的問題。
2.新增點選事件
1)在Adapter中建立一個實現點選介面:
public interface OnItemClickLitener {
void onItemClick(View view, int position);
}
2)在Adapter中新增介面設定方法:
private OnItemClickLitener mOnItemClickListener = null;
public void setOnItemClickListener(OnItemClickLitener listener) {
this.mOnItemClickListener = listener;
}
3)觸發itemClick回撥程式碼:
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.mTextView .setText(data.get(position));
holder.mTextView.setTag(holder.getLayoutPosition());
holder.mTextView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.item_text:
mOnItemClickListener.onItemClick(v, (int ) v.getTag());
break;
}
}
4)activity中註冊介面到Adapter中:
public class ItemClickListViewActivity extends AppCompatActivity {
/**
* view
*/
private RecyclerView recyclerView;
/**
* 用來確定每一個item如何進行排列擺放,何時展示和隱藏
*/
private LinearLayoutManager layoutManager;
/**
* 介面卡
*/
private MyItemClickAdapter mAdapter;
private ArrayList<String> data = new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
}
/**
* 初始化佈局元件
*/
private void initView() {
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
//建立預設的線性LayoutManager
layoutManager = new LinearLayoutManager(this);
// layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(layoutManager);
//如果可以確定每個item的高度是固定的,設定這個選項可以提高效能
recyclerView.setHasFixedSize(true);
}
/**
* 初始化資料
*/
private void initData() {
for (int i = 0; i < 100; i++) {
data.add(i + "--->click");
}
//建立並設定Adapter
mAdapter = new MyItemClickAdapter(data);
recyclerView.setAdapter(mAdapter);
recyclerView.setItemAnimator(new DefaultItemAnimator());
mAdapter.setOnItemClickListener(new MyItemClickAdapter.OnItemClickLitener() {
@Override
public void onItemClick(View view, int position) {
if(position ==2){
mAdapter.addItem("add click", 4);
Toast.makeText(ItemClickListViewActivity.this, "增加資料" + position, Toast.LENGTH_SHORT).show();
}else if(position ==3) {
mAdapter.removeItem(2);
Toast.makeText(ItemClickListViewActivity.this, "刪除資料" + position, Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(ItemClickListViewActivity.this, "選中" + position, Toast.LENGTH_SHORT).show();
}
}
});
}
}
以上程式碼就可以為RecyclerView新增item點選事件了。
3.Item增加和刪除
在adpater中增加如下兩個方法:
1)新增資料:
public void addItem(String content, int position) {
data.add(position, content);
notifyItemInserted(position);
}
2)刪除資料:
public void removeItem(int position) {
data.remove(position);
notifyItemRemoved(position);
}
activity中呼叫上面兩個方法,實現增加跟刪除item
mAdapter.setOnItemClickListener(new MyItemClickAdapter.OnItemClickLitener() {
@Override
public void onItemClick(View view, int position) {
if(position ==2){
mAdapter.addItem("add click", 4);
Toast.makeText(ItemClickListViewActivity.this, "增加資料" + position, Toast.LENGTH_SHORT).show();
}else if(position ==3) {
mAdapter.removeItem(2);
Toast.makeText(ItemClickListViewActivity.this, "刪除資料" + position, Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(ItemClickListViewActivity.this, "選中" + position, Toast.LENGTH_SHORT).show();
}
}
});
4.解決增加或者刪除position混亂的問題:
照Google文件描述在使用了notifyItemInserted時候原來位置的position會加1,但是事實證明資料的position位置毫無變化,暫且認為google工程師的錯誤吧,但是我們還是要繼續使用。一般有兩種解決辦法:
1)保留刪除跟新增動畫效果:notifyItemRemoved(position);notifyItemInserted(position);從原始碼可以看出,他只是重新整理當前插入或者刪除的item,不會觸發onBindViewHolder,所以插入或者刪除的item的下方的item的postion會有混亂。所以我們手動來重新整理,程式碼如下:
public void removeItem(int position) {
data.remove(position);
notifyItemRemoved(position);
// 加入如下程式碼保證position的位置正確性
if (position != data.size() - 1) {
notifyItemRangeChanged(position, data.size() - position);
}
}
public void addItem(String content, int position) {
data.add(position, content);
notifyItemInserted(position);
// 加入如下程式碼保證position的位置正確性
if (position != data.size() - 1) {
notifyItemRangeChanged(position, data.size() - position);
}
}
2)去掉動畫:直接使用notifyDataSetChanged();因為使用notifyDataSetChanged();後,動畫則消失了。
public void removeItem(int position) {
data.remove(position);
notifyItemRemoved(position);
notifyDataSetChanged();
}
public void addItem(String content, int position) {
data.add(position, content);
notifyItemInserted(position);
notifyDataSetChanged();
}
5.完整程式碼
activity程式碼:
package com.test.recyclerview.itemclick;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Toast;
import com.test.recyclerview.R;
import java.util.ArrayList;
public class ItemClickListViewActivity extends AppCompatActivity {
/**
* view
*/
private RecyclerView recyclerView;
/**
* 用來確定每一個item如何進行排列擺放,何時展示和隱藏
*/
private LinearLayoutManager layoutManager;
/**
* 介面卡
*/
private MyItemClickAdapter mAdapter;
private ArrayList<String> data = new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
}
/**
* 初始化佈局元件
*/
private void initView() {
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
//建立預設的線性LayoutManager
layoutManager = new LinearLayoutManager(this);
// layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(layoutManager);
//如果可以確定每個item的高度是固定的,設定這個選項可以提高效能
recyclerView.setHasFixedSize(true);
}
/**
* 初始化資料
*/
private void initData() {
for (int i = 0; i < 100; i++) {
data.add(i + "--->click");
}
//建立並設定Adapter
mAdapter = new MyItemClickAdapter(data);
recyclerView.setAdapter(mAdapter);
recyclerView.setItemAnimator(new DefaultItemAnimator());
mAdapter.setOnItemClickListener(new MyItemClickAdapter.OnItemClickLitener() {
@Override
public void onItemClick(View view, int position) {
if(position ==2){
mAdapter.addItem("add click", 4);
Toast.makeText(ItemClickListViewActivity.this, "增加資料" + position, Toast.LENGTH_SHORT).show();
}else if(position ==3) {
mAdapter.removeItem(2);
Toast.makeText(ItemClickListViewActivity.this, "刪除資料" + position, Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(ItemClickListViewActivity.this, "選中" + position, Toast.LENGTH_SHORT).show();
}
}
});
}
}
adapter程式碼:
package com.test.recyclerview.itemclick;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.test.recyclerview.R;
import java.util.ArrayList;
public class MyItemClickAdapter extends RecyclerView.Adapter<MyItemClickAdapter.ViewHolder> implements View.OnClickListener {
private OnItemClickLitener mOnItemClickListener = null;
public void setOnItemClickListener(OnItemClickLitener listener) {
this.mOnItemClickListener = listener;
}
private ArrayList<String> data;
public MyItemClickAdapter(ArrayList<String> data) {
this.data = data;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.activity_item, viewGroup, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.mTextView.setText(data.get(position));
holder.mTextView.setTag(holder.getLayoutPosition());
holder.mTextView.setOnClickListener(this);
}
@Override
public int getItemCount() {
return data == null ? 0 : data.size();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.item_text:
mOnItemClickListener.onItemClick(v, (int) v.getTag());
break;
}
}
//自定義的ViewHolder,持有每個Item的的所有介面元素
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView mTextView;
public ViewHolder(View view) {
super(view);
mTextView = (TextView) view.findViewById(R.id.item_text);
}
}
public void removeItem(int position) {
data.remove(position);
notifyItemRemoved(position);
// 加入如下程式碼保證position的位置正確性
if (position != data.size() - 1) {
notifyItemRangeChanged(position, data.size() - position);
}
}
public void addItem(String content, int position) {
data.add(position, content);
notifyItemInserted(position);
// 加入如下程式碼保證position的位置正確性
if (position != data.size() - 1) {
notifyItemRangeChanged(position, data.size() - position);
}
}
public interface OnItemClickLitener {
void onItemClick(View view, int position);
}
}
6.完整程式碼下載地址如下所示:
歡迎一起交流討論
群號:469890293
相關推薦
RecyclerView詳細介紹-----解決點選事件,重新整理錯誤(二)
1. 前言 RecyclerView 沒有提供類似ListView的setOnItemClickListener方法,所以只有我們自己為RecyclerView新增點選事件, 本篇文章主要介紹如何新增點選事件,進行Item增加和刪除,並且解決Recyc
10.RecyclerView中的item點選事件,如何實現
recyclerview的使用方法和listview大同小異,但是使用的adapter確實非常不一樣: 1.需要在adapter宣告onclickListener()介面, 2.然後建立介面物件, 3.然後實現介面方法, 4.之後在adapte中的vieholder中繫結例
商品詳情介面點選跳轉到購物車(二)購物車介面
//佈局檔案 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-aut
android recyclerview 上下滑動導致點選事件和資料錯亂問題解決
今天遇到一個奇怪的Bug 上下滑動Item時候 再往上滑 撥打電話 與剛開始不一致,網上很多人說setTag種種,但並沒有什麼卵用,很鄙視那些複製貼上的 兩種解決方案 getItemViewType(int position){return position} // 這樣多種佈局
recyclerview巢狀GridView去遮蔽後者的點選事件,而是前者響應到事件。
無論是標題中的巢狀方式,還是其它列表控制元件之間的巢狀,都適用。 1、在GirdView的所在佈局的根佈局中設定改屬性: android:descendantFocusability="blacksDescendants" 2、動態設定GirdView的如下屬性: gridvi
解決datetimepicker不能觸發點選事件,日期外掛位置偏移,日期範圍限制的問題
最初的問題: 一開始所遇到的問題是相對簡單的,就是今天的日期是3-20,但是卻可以選擇20號之後的日期。 html程式碼: <form action="web?module=stwmgr&action=Dataprocessing&method=g
RecyclerView的Item點選事件,增加刪除Item瀑布流動畫效果,長按拖動Item,RecyclerView複雜佈局、實現新聞頻道選擇器
RecyclerView的Item點選事件的實現,增加和刪除Item使用瀑布流動畫效果,長按拖動Item,RecyclerView複雜佈局的實現使用、RecyclerView去實現今日頭條新聞頻道選擇器。 使用ItemTouchHelper實現Item的拖動交換,由於Recy
為RecyclerView打造萬能介面卡,點選事件,5.0水波紋點選效果
一.前言 最近使用到RecyclerView,RecyclerView使用詳解戳這裡,由於使用過張鴻洋大神的ListView萬能Adapter,感覺RecyclerView的Adapter編寫還是太麻煩了,而且沒有點選事件,ok,參考ListView的萬能Ad
Android中Recyclerview使用7----條目中按鈕點選事件,在activity中呼叫(介面回撥)
0引入Recyclerview的支援庫 compile 'com.android.support:recyclerview-v7:23.4.0' 1效果圖: 2程式碼: 2.1MainActivity中: <span style="font-size:18p
RecyclerView 實現瀑布流及點選事件,含點選回撥的介面
RecyclerView 實現瀑布流及點選事件 public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> { private List
cocos2d-x中解決點選事件上層響應,下層不響應
解決方案是重寫一個Layer,加在上下層中間,即可只響應上層事件,阻斷了下層的事件,設定優先順序,程式碼如下 #ifndef _TouchBlockLayer_H_ #define _TouchBlockLayer_H_ class TouchBlockLayer:
andorid佈局layout監聽點選事件,佈局內的imageButton無法響應解決方法
今天發現這個問題,使用的是相對佈局,裡面包含一個TextView與ImageButton,相對佈局監聽了onClickListener,本來想整個佈局點選後都能響應一個事件,結果發現ImageButton無法響應。 嘗試了給imagebutton增加 clickable=t
自定義的tabbar在跳轉之後隱藏tabbar後,tabbar原來的位置不能響應點選事件,這樣解決
yourInnerViewController.hidesBottomBarWhenPushed = YES; [self.navigationController pushViewControlle
由於某種特殊需求,我需要在winform程式中模擬滑鼠點選事件,經過Google,終於找到了如下解決方案。
來自:http://outofmemory.cn/code-snippet/1708/how-winform-moni-shubiao-click-event using System; using System.Windows.Forms; using System.Ru
RecyclerView載入不同item並實現其item點選事件,實現新增常用應用的功能
先上效果圖吧 點選加號 勾選需要的應用點選新增 這裡出現了三種item的樣式,一種是加號,一種是應用圖示加文字,最後一種是應用圖示加文字還有個checkBox 這裡RecyclerView是配合CardView使用的。 在AS中使用RecyclerView需要先在buil
jquery定義之後的按鈕點選事件,會產生累計的情況
使用jquery的on()方法為元素綁定了點選事件,點選同時傳送請求。完成後看效果,第一次點選沒有問題。再一次點選後發現傳送了兩次請求,後面再點擊發現請求的數量越來越多。當排查之後,發現只有一個元素綁定了事件,而且只調用了一次之後,得出最有可能的一種情況,就是點選事件被累加綁定了。 $("#ad
可能是最詳細的Android點選事件處理詳解(三)
前兩篇文章: 可能是最詳細的Android點選事件處理詳解 可能是最詳細的Android點選事件處理詳解(二) 這裡再次延伸一下,在ScrollView和RecyclerView巢狀中touch事件的傳遞過程,以及巢狀滑動衝突的問題。 如上圖,外層是一個Neste
可能是最詳細的Android點選事件處理詳解(二)
上一篇我們主要詳細描述了touch事件在各層的傳遞 本篇文章主要是對比touch在不可滾動和可滾動的ViewGroup事件的傳遞過程 如上圖: - 左圖:是ViewGroup巢狀View,不可滑動 - 右圖:也是ViewGroup(RecyclerView)巢
可能是最詳細的Android點選事件處理詳解
面試的時候,很多時候都會問到Touch事件的傳遞,而且問法角度都有所不同,但是還是會遵循基本的事件傳遞規則的,可能他問的你沒處理過,但是根據基本規則慢慢思考來回答,都不會錯。 一,簡介 首先我們知道touch事件 主要是是在三個方法中傳遞和處理的。分別是:
jquery的點選事件,非動態載入點選與動態載入點選
jquery的點選事件,非動態載入點選與動態載入點選寫法不同 1.非動態載入點選 <div id="clickdemo"> <ul> <li>1<li> </ul> </div>點選1觸發 $