Android GridView单元格顺序更改

时间:2018-08-15 23:00:52

标签: android gridview android-gridview

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

GridView when app first opened

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

After scrolling down a few rows and then back up

1 个答案:

答案 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不是第一列,则要使其可见,但是如果 是第一列,则不能使其不可见。