gpt4 book ai didi

android - RecyclerView getChildAt(position) 返回 null

转载 作者:太空宇宙 更新时间:2023-11-03 12:15:27 31 4
gpt4 key购买 nike

  • 我在我的应用程序中实现了 Recyclerview,我需要在其项目上单击更新另一个 ListView ,这就是我在 Activity 中实现 onClick 事件的原因。它工作正常。
  • 但我还需要高亮 RecyclerView 选中的 View ,其他的都保持正常。
  • 为此,我使用 RecyclerView getChild 方法使所有 View 正常化,然后选择 View 突出显示。
  • 我意识到它仅适用于 RecyclerView 的可见 View 。但是我需要使 Recyclerview 的所有 View 正常化,如果我使用 getChildAt 的位置更大,那么总可见计数将返回 Null Pointer 异常。
    • 我得到的日志

E/Item Pos: 29

E/Item Rv: 15

E/Child Adapter: 30

主 Activity .java

public class MainActivity extends Activity {
RecyclerView reView;
ArrayList<RvModel> rvModels;
revAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
reView = (RecyclerView) findViewById(R.id.reView);
reView.setLayoutManager(new GridLayoutManager(MainActivity.this, 3));

rvModels = new ArrayList<>();
adapter = new revAdapter(MainActivity.this, rvModels);
reView.setAdapter(adapter);
prepareData();
reView.addOnItemTouchListener(new RecyclerItemClickListener(MainActivity.this, reView, new RecyclerItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Log.e("Item Pos", "" + position);
Log.e("Item Rv", "" + reView.getChildCount());
Log.e("Child Adapter", "" + reView.getAdapter().getItemCount());

for (int i = 0; i < reView.getChildCount(); i++) {
View v = reView.getChildAt(i);
TextView txtText = (TextView) v.findViewById(R.id.txtText);

txtText.setBackgroundColor(Color.WHITE);
txtText.setTextColor(Color.BLUE);
}
TextView txtText = (TextView) view.findViewById(R.id.txtText);
txtText.setBackgroundColor(Color.BLUE);
txtText.setTextColor(Color.WHITE);
}

@Override
public void onLongItemClick(View view, int position) {

}
}));
}

private void prepareData() {
rvModels.clear();
for (int i = 0; i < 30; i++) {
RvModel rvModel = new RvModel();
rvModel.setTitle("Item : " + i);
rvModels.add(rvModel);
}
adapter.notifyDataSetChanged();
}
}

revAdapter.java

public class revAdapter extends RecyclerView.Adapter<revAdapter.ViewHolder> {
Context context;
ArrayList<RvModel> rvModels;
LayoutInflater inflater;

public revAdapter(Context context, ArrayList<RvModel> rvModels) {
this.context = context;
this.rvModels = rvModels;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

public class ViewHolder extends RecyclerView.ViewHolder {
ImageView ivIcon;
TextView txtText;

public ViewHolder(View itemView) {
super(itemView);
ivIcon = (ImageView) itemView.findViewById(R.id.ivIcon);
txtText = (TextView) itemView.findViewById(R.id.txtText);
}
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = inflater.inflate(R.layout.rv_raw, parent, false);
return new ViewHolder(itemView);
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
RvModel rvModel = rvModels.get(position);
holder.txtText.setText(rvModel.getTitle());
}

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

@Override
public int getItemViewType(int position) {
return position;
}
}

rv_raw.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp">

<ImageView
android:id="@+id/ivIcon"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@mipmap/ic_launcher" />

<TextView
android:id="@+id/txtText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>

最佳答案

问题是像 ListView 这样的 recyclerView 有多少 subview (项目)取决于你的屏幕尺寸,而不是你有多少项目。它可以防止应用程序出现 OOM 异常。例如,如果您有 100 万个项目,那么根据您的逻辑,回收者 View 必须创建 100 万个 subview ,这很糟糕。您可以阅读有关 ListView 的更多信息 here (回收者 View 以相同的方式工作)

所以在您的情况下,在 onClick 事件中,您不需要找到 View 并更改它。您需要更改一些所谓的“设置”并编写 notifyDataSetChangednotifyItemChanged 以获得更多优化。

此外,我已经检查了您的代码,我求求您了。请,请删除这个重写函数:

@Override
public int getItemViewType(int position) {
return position;
}

您对所有元素使用相同的支架,因此在您的回收站 View 中只有一种类型的 View 。以这种方式重写此方法,您告诉回收者 View ,每个项目都使用不同的布局,这会降低性能。

所以,根据你的问题,你会有某种:

reView.addOnItemTouchListener(new RecyclerItemClickListener(MainActivity.this, reView, new RecyclerItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Log.e("Item Pos", "" + position);
Log.e("Item Rv", "" + reView.getChildCount());
Log.e("Child Adapter", "" + reView.getAdapter().getItemCount());

if (!adapter.isChecked(position)) {
adapter.setChecked(position);
}
}

@Override
public void onLongItemClick(View view, int position) {

}
}));

在适配器中:

private int checkedPosition = -1;

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
RvModel rvModel = rvModels.get(position);
holder.txtText.setText(rvModel.getTitle());

if (position == checkedPosition) {
txtText.setBackgroundColor(Color.BLUE);
txtText.setTextColor(Color.WHITE);
} else {
txtText.setBackgroundColor(Color.WHITE);
txtText.setTextColor(Color.BLUE);
}
}

public boolean isChecked(int position) {
return checkedPosition == position;
}

public void setChecked(int position) {
int prevChecked = checkedPosition;
checkedPosition = position;

if (prevChecked != -1) {
notifyItemChanged(prevChecked);
}
notifyItemChanged(checkedPosition)
}

关于android - RecyclerView getChildAt(position) 返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38474645/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com