在填充GridView时,我遇到一个非常奇怪的问题-第一次加载时,一切看起来都很好,但是滚动最终导致单元格中的数据移动到其他位置。在下面的示例中,我只有一个数字0-800的ArrayList和一个8列的网格。加载时,第一行中包含0-7,第二行中包含8-15,依此类推,每行的第一单元格中的值都不同。但是,滚动后,第一列的值将更改。这是代码-这让我发疯了!
MainActivity.java:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayList<Integer> positions = new ArrayList<Integer>();
for(int i=0;i<800;i++) {
positions.add(i);
}
GridView gvVals = findViewById(R.id.gvVals);
CellAdapter adapter = new CellAdapter(this, new ArrayList<Integer>());
adapter = new CellAdapter(this, positions);
gvVals.setAdapter(adapter);
}
Cell Adapter.java:
public class CellAdapter extends ArrayAdapter<Integer> {
private Context context;
public CellAdapter(Context context, ArrayList<Integer> vals) {
super(context, 0, vals);
this.context = context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v;
if (convertView == null) {
v = LayoutInflater.from(getContext()).inflate(R.layout.activity_cell, parent, false);
} else {
v = (View)convertView;
}
TextView tvDay = v.findViewById(R.id.tvVal);
tvDay.setVisibility(View.VISIBLE);
if(position % 8 == 0) {
tvDay.setText("ST:"+position);
}
else
{
v.findViewById(R.id.btnM).setVisibility(View.VISIBLE);
((Button)v.findViewById(R.id.btnM)).setText(position + " ");
tvDay.setText(" ");
}
return v;
}
ActivityMain.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<GridView
android:id="@+id/gvVals"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="60dp"
android:numColumns="8"/>
</android.support.constraint.ConstraintLayout>
ActivityCell.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tvVal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:visibility="invisible"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:id="@+id/btnM"
android:layout_width="0dp"
android:layout_weight=".34"
android:layout_height="20dp"
android:text="M"
android:background="@color/colorAccent"
android:minWidth="0dp"
android:visibility="invisible"/>
</LinearLayout>
</android.support.constraint.ConstraintLayout>
应用首次打开时的GridView
向下滚动几行然后向上备份
答案 0 :(得分:0)
更改此:
TextView tvDay = v.findViewById(R.id.tvVal); tvDay.setVisibility(View.VISIBLE); if(position % 8 == 0) { tvDay.setText("ST:"+position); } else { v.findViewById(R.id.btnM).setVisibility(View.VISIBLE); ((Button)v.findViewById(R.id.btnM)).setText(position + " "); tvDay.setText(" "); }
对此:
boolean firstColumn = position % 8 == 0;
TextView tvDay = v.findViewById(R.id.tvVal);
tvDay.setVisibility(firstColumn ? View.VISIBLE : View.GONE);
Button btnM = v.findViewById(R.id.btnM);
btnM.setVisibility(firstColumn ? View.GONE : View.VISIBLE);
if(firstColumn) {
tvDay.setText("ST:"+position);
}
else
{
btnM.setText(position + " ");
}
使用RecyclerView时务必要确保每次都始终更新每个视图,这一点很重要。这是因为旧的视图持有者会被回收,因此,如果您仅在某些时间做一些事情,它可能会被覆盖或覆盖“预期”行为。
以前,如果btnM
不是第一列,则要使其可见,但是如果 是第一列,则不能使其不可见。