Android recyclerView findViewHolderForAdapterPosition返回null
我想以编程方式单击recyclerView中的项目,我发现可以这样做: 但它对我不起作用,findViewHolderForAdapterPosition只返回null 我的代码中遗漏了什么吗 HistoryListAdapter:Android recyclerView findViewHolderForAdapterPosition返回null,android,android-recyclerview,Android,Android Recyclerview,我想以编程方式单击recyclerView中的项目,我发现可以这样做: 但它对我不起作用,findViewHolderForAdapterPosition只返回null 我的代码中遗漏了什么吗 HistoryListAdapter: public class HistoryListAdapter extends RecyclerView.Adapter<HistoryListAdapter.ViewHolder> { private static ArrayList<Recor
public class HistoryListAdapter extends RecyclerView.Adapter<HistoryListAdapter.ViewHolder> {
private static ArrayList<RecordItem> recordItems;
private static FragmentActivity activity;
private static RecordList recordList;
public HistoryListAdapter(ArrayList<RecordItem> recordItems, FragmentActivity FA, RecordList FRL) {
this.recordItems = recordItems;
this.activity = FA;
this.recordList = FRL;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recorditem, parent, false);
return new ViewHolder(itemLayoutView);
}
@Override
public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
// TextView setText ...
}
// Return the size of the itemsData (invoked by the layout manager)
@Override
public int getItemCount() {
return recordItems.size();
}
// inner class to hold a reference to each item of RecyclerView
public static class ViewHolder extends RecyclerView.ViewHolder{
public TextView result, datetime;
public ViewHolder(View itemLayoutView) {
super(itemLayoutView);
itemLayoutView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (activity != null) {
// do something...
}
}
});
result = (TextView) itemLayoutView.findViewById(R.id.result);
heartrate = (TextView) itemLayoutView.findViewById(R.id.heartrate);
datetime = (TextView) itemLayoutView.findViewById(R.id.datetime);
}
}
}
我省略了一些代码,但它不应影响代码的整体结构。根据:
如果已调用notifyDataSetChanged(),但新布局没有
尚未计算,自新的
在计算布局之前,视图的位置是未知的
使用findViewHolderForAdapterPosition()
是不安全的
当您在
listView.swapAdapter(listadapter,false)之后调用此方法时
结果总是会得到一个null
,因为将调用notifyDataSetChanged()
。嘿,我用这种方法解决了这个问题:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private TextView mTotalSum;
protected int mSum;
protected ArrayList<BasketRVAdapter.ViewHolder> mViewHolders;
public BasketRVAdapter(JSONArray recyclerItems, Context context, TextView totalSum) {
super(recyclerItems, context);
mTotalSum = totalSum;
mViewHolders = new ArrayList<>();
}
@Override
public RecyclerView.ViewHolder onCreateSwipeViewHolder(ViewGroup parent, int i) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.view_basket_rv_item, parent, true);
return new ViewHolder(view);
}
@Override
public void onBindSwipeViewHolder(final RecyclerView.ViewHolder viewHolder, int position) {
final BasketRVAdapter.ViewHolder holder = (BasketRVAdapter.ViewHolder) viewHolder;
JSONObject object;
try {
object = mRecyclerItems.getJSONObject(position);
final int priceValue = object.getInt("price");
final int quantityValue = object.getInt("quantity");
holder.setId(object.getInt("id"));
holder.title.setText(object.getString("title"));
holder.price.setText(String.format(mContext.getString(R.string.price), priceValue));
holder.quantity.setText(String.valueOf(quantityValue));
holder.sum.setText(String.valueOf(priceValue * quantityValue));
holder.quantity.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
String value = holder.quantity.getText().toString();
if (value.equals("")) {
return;
}
if (value.equals("0")) {
Toast.makeText(mContext, R.string.null_value_error, Toast.LENGTH_SHORT).show();
return;
}
holder.sum.setText(String.valueOf(priceValue * Integer.valueOf(value)));
setTotalSum();
}
});
mViewHolders.add(holder);
mSum += priceValue * quantityValue;
if (position == getItemCount() - 1) {
mTotalSum.setText(String.format(mContext.getString(R.string.total_sum), mSum));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public SwipeConfiguration onCreateSwipeConfiguration(Context context, int i) {
return new SwipeConfiguration.Builder(context)
.setLeftSwipeBehaviour(SwipeConfiguration.SwipeBehaviour.NORMAL_SWIPE)
.setRightSwipeBehaviour(SwipeConfiguration.SwipeBehaviour.NO_SWIPE)
.setLeftBackgroundColorResource(R.color.dt_basket_deleted)
.setLeftUndoDescription(R.string.deleted)
.setDescriptionTextColorResource(R.color.dt_white)
.setLeftUndoable(true)
.build();
}
@Override
public void onSwipe(int i, int i1, RecyclerView.ViewHolder holder) {
try {
if (i1 == SWIPE_LEFT) {
remove(i);
notifyItemRemoved(i);
mViewHolders.remove(i);
setTotalSum();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
public int getSum() {
return mSum;
}
public void setTotalSum() {
int totalSum = 0;
for (BasketRVAdapter.ViewHolder holder : mViewHolders) {
totalSum += Integer.valueOf(holder.sum.getText().toString());
}
mSum = totalSum;
mTotalSum.setText(String.format(mContext.getString(R.string.total_sum), totalSum));
}
public static class ViewHolder extends RecyclerView.ViewHolder {
@Bind(R.id.trade_title)
public TextView title;
@Bind(R.id.trade_price)
public TextView price;
@Bind(R.id.trade_quantity)
public EditText quantity;
@Bind(R.id.sum)
public TextView sum;
private int mId;
public ViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
public int getId() {
return mId;
}
public void setId(int id) {
mId = id;
}
}}
公共类MyAdapter扩展了RecyclerView.Adapter{
私有文本视图mTotalSum;
受保护的内部mSum;
受保护的ArrayList多视图文件夹;
public BasketrAdapter(JSONArray recyclerItems、上下文、TextView totalSum){
超级(循环使用,上下文);
mTotalSum=总和;
mViewHolders=newarraylist();
}
@凌驾
public RecyclerView.ViewHolder onCreateSwipeViewHolder(视图组父级,int i){
View=LayoutInflater.from(parent.getContext())
.充气(右布局、视图、篮子、房车项目、父项、真实);
返回新的ViewHolder(视图);
}
@凌驾
BindSwipeViewHolder上的公共无效(最终RecyclerView.ViewHolder ViewHolder,内部位置){
final basketrAdapter.ViewHolder=(basketrAdapter.ViewHolder)ViewHolder;
JSONObject对象;
试一试{
object=mRecyclerItems.getJSONObject(位置);
final int priceValue=object.getInt(“价格”);
final int quantityValue=object.getInt(“数量”);
holder.setId(object.getInt(“id”));
holder.title.setText(object.getString(“title”);
holder.price.setText(String.format(mContext.getString(R.String.price),priceValue));
holder.quantity.setText(String.valueOf(quantityValue));
holder.sum.setText(String.valueOf(priceValue*quantityValue));
holder.quantity.addTextChangedListener(新的TextWatcher(){
@凌驾
更改前的公共无效(CharSequence CharSequence,int i,int i1,int i2){
}
@凌驾
public void onTextChanged(CharSequence CharSequence,int i,int i1,int i2){
}
@凌驾
public void PostTextChanged(可编辑){
字符串值=holder.quantity.getText().toString();
if(值等于(“”){
返回;
}
if(值等于(“0”)){
Toast.makeText(mContext,R.string.null_value_error,Toast.LENGTH_SHORT).show();
返回;
}
holder.sum.setText(String.valueOf(priceValue*Integer.valueOf(value));
setTotalSum();
}
});
mViewHolders.add(holder);
mSum+=价格值*数量值;
if(position==getItemCount()-1){
setText(String.format(mContext.getString(R.String.total_sum),mSum));
}
}捕获(JSONException e){
e、 printStackTrace();
}
}
@凌驾
公共SwipeConfiguration onCreateSwipeConfiguration(上下文,int i){
返回新的swipConfiguration.Builder(上下文)
.SetLeftSwipeBehavior(SwipeConfiguration.SwipeBehavior.NORMAL_SWIPE)
.SetRightSwipeBehavior(SwipeConfiguration.SwipeBehavior.NO_SWIPE)
.setLeftBackgroundColorResource(R.color.dt_已删除)
.setLeftUndoDescription(R.string.deleted)
.setDescriptionTextColorResource(R.color.dt_白色)
.setLeftUndoable(真)
.build();
}
@凌驾
公共void onswip(int i、int i1、RecyclerView.ViewHolder){
试一试{
如果(i1==向左滑动){
删除(i);
(i)删去第(i)款;
删除(i)项;
setTotalSum();
}
}捕获(JSONException e){
e、 printStackTrace();
}
}
公共整数getSum(){
返回mSum;
}
公共无效setTotalSum(){
整数总和=0;
用于(BasketrAdapter.ViewHolder:mViewHolders){
totalSum+=Integer.valueOf(holder.sum.getText().toString());
}
mSum=总和;
setText(String.format(mContext.getString(R.String.total_sum),totalSum));
}
公共静态类ViewHolder扩展了RecyclerView.ViewHolder{
@绑定(R.id.trade_title)
公共文本视图标题;
@绑定(R.id.交易价格)
公共文本视图价格;
@绑定(R.id.trade\u数量)
公共编辑文本数量;
@绑定(R.id.sum)
公共文本视图和;
私人int mId;
公共视图持有者(视图项视图){
超级(项目视图);
ButterKnife.bind(这个,itemView);
}
公共int getId(){
中途返回;
}
公共无效集合id(内部id){
mId=id;
}
}}
listView.postDelayed(new Runnable()
{
@Override
public void run()
{
if(listView.findViewHolderForAdapterPosition(0)!=null )
{
listView.findViewHolderForAdapterPosition(0).itemView.performClick();
}
}
},50);
postAndNotifyAdapter(new Handler(),mRecyclerView);
protected void postAndNotifyAdapter(final Handler handler, final RecyclerView recyclerView) {
handler.post(new Runnable() {
@Override
public void run() {
if ( recyclerView.findViewHolderForLayoutPosition(0)!=null) {
// This will call first item by calling "performClick()" of view.
recyclerView.findViewHolderForLayoutPosition(0).itemView.performClick();
} else {
//
postAndNotifyAdapter(handler, recyclerView);
}
}
});
}
我不建议使用后期延迟。虽然它可以工作,但时间是任意的 使用recyclerview上的OnPreDrawListener,计时将与下一个绘图周期对齐,并且可以访问可见项目。您可以执行以下操作:
listView.postDelayed(new Runnable()
{
@Override
public void run()
{
if(listView.findViewHolderForAdapterPosition(0)!=null )
{
listView.findViewHolderForAdapterPosition(0).itemView.performClick();
}
}
},50);
postAndNotifyAdapter(new Handler(),mRecyclerView);
protected void postAndNotifyAdapter(final Handler handler, final RecyclerView recyclerView) {
handler.post(new Runnable() {
@Override
public void run() {
if ( recyclerView.findViewHolderForLayoutPosition(0)!=null) {
// This will call first item by calling "performClick()" of view.
recyclerView.findViewHolderForLayoutPosition(0).itemView.performClick();
} else {
//
postAndNotifyAdapter(handler, recyclerView);
}
}
});
}
我知道这已经很晚了,但可能对Kotlin时代的其他人有帮助:
binding.recycler.post {
val view = binding.recycler.findViewHolderForAdapterPosition(position)?.itemView?.performClick()
}