【问题标题】:Android GridView cell sequence changingAndroid GridView 单元格序列变化
【发布时间】:2018-08-15 23:00:52
【问题描述】:

在填充 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

向下滚动几行然后向上滚动后

​​>

【问题讨论】:

    标签: android gridview android-gridview


    【解决方案1】:

    改变这个:

    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 不是第一列,您将使其可见,但如果它是第一列,则不会使其不可见。

    【讨论】:

    • 非常感谢,这已经困扰我好几天了!
    猜你喜欢
    • 1970-01-01
    • 2011-04-13
    • 1970-01-01
    • 1970-01-01
    • 2018-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-07
    相关资源
    最近更新 更多