Обновление данных адаптера и уведомление об изменении на setOnItemClickListener - PullRequest
0 голосов
/ 03 ноября 2018

при использовании обычного строкового массива в качестве источника данных для gridview просто прямое изменение массива и вызов notifydatachange работает, но когда данные являются пользовательским адаптером, то gridview не обновляется.
Я знаю, что изменение текстового представления текущей ячейки выполнимо, но я хочу изменить два GridView, когда значение одной ячейки изменяется, когда два адаптера имеют один и тот же объект String и согласно огромным комментариям в Является ли Java "передачей по ссылке" или "передачей" -by-value "? объект в java передается по ссылке, и оба адаптера должны быть изменены, но в моем случае ни один из них не изменяется.

Сетка ячейки пользовательского класса

public class GridCell {
private static final String TAG = "GridCell";
private String cell_value;

public GridCell(String cell_value) {
    this.cell_value = cell_value;
}

public String getcell_value() {
    return cell_value;
}
public void setcell_value(String c) {
    this.cell_value = c;
}
}

Код адаптера

public class GridCellAdapter extends ArrayAdapter<GridCell> {
public GridCellAdapter(Context context, int textViewId, ArrayList<GridCell> cells) {
    super(context, textViewId, cells);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // Get the data item for this position
    GridCell cell = getItem(position);
    // Check if an existing view is being reused, otherwise inflate the view
    if (convertView == null) {
        convertView = LayoutInflater.from(getContext()).inflate(R.layout.gv_item_fixedline, parent, false);
        // following code is moved out of if block AFTER Ben's answer  below. so to avoid other user might suggest same solution
        //TextView tv = (TextView) convertView.findViewById(R.id.cellval);
        //tv.setText(cell.getcell_value());
    }
    TextView tv = (TextView) convertView.findViewById(R.id.cellval);
    tv.setText(cell.getcell_value());
// save the object so that this object can be modified by setOnItemClickListener

    convertView.setTag(cell);
    return convertView;
}

@Override
public int getCount() {
    return super.getCount();
}
}

Основная деятельность

public class MainActivity extends AppCompatActivity {

GridView gridView1;
GridView gridView2;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // init gridview

    // Construct the data source for GridView1
    ArrayList<GridCell> arrayOfCells1 = new ArrayList<GridCell>();
    // Create the adapter to convert the array to views
    final GridCellAdapter gcAdapter1 = new GridCellAdapter(this, R.layout.gv_item_fixedline, arrayOfCells1);
    gridView1 = (GridView) findViewById(R.id.gridView1);
    gridView1.setAdapter(gcAdapter1);


    // Construct the data source for GridView2
    ArrayList<GridCell> arrayOfCells2 = new ArrayList<GridCell>();
    // Create the adapter to convert the array to views
    final GridCellAdapter gcAdapter2 = new GridCellAdapter(this, R.layout.gv_item_fixedline, arrayOfCells2);
    gridView2 = (GridView) findViewById(R.id.gridView2);
    gridView2.setAdapter(gcAdapter2);

    for (int i = 1; i <= 3; i++) {
        // both adapter now has same object reference. am I right here?
        GridCell tmp = new GridCell("U");
        gcAdapter1.add(tmp);
        gcAdapter2.add(tmp);
    }


    gridView1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            // this object is shared by both adapter 
            GridCell cell = (GridCell) view.getTag();
            Log.d(TAG, "onItemClick: " + cell.getcell_value());
            cell.setcell_value("X");
            Log.d(TAG, "onItemClick: modified :" + cell.getcell_value());
            Toast.makeText(getApplicationContext(), Integer.toString(position), Toast.LENGTH_SHORT).show();
        }
    });

    gcAdapter1.notifyDataSetChanged();
    gcAdapter2.notifyDataSetChanged();

}


}

1 Ответ

0 голосов
/ 03 ноября 2018

В вашем getView() методе у вас есть этот код:

if (convertView == null) {
    convertView = LayoutInflater.from(getContext()).inflate(R.layout.gv_item_fixedline, parent, false);
    TextView tv = (TextView) convertView.findViewById(R.id.cellval);
    tv.setText(cell.getcell_value());
}

Вы должны переместить вызов setText() за пределы блока if:

if (convertView == null) {
    convertView = LayoutInflater.from(getContext()).inflate(R.layout.gv_item_fixedline, parent, false);
}

TextView tv = (TextView) convertView.findViewById(R.id.cellval);
tv.setText(cell.getcell_value());

В противном случае текст не будет обновляться при изменении данных (при условии, что представление будет переработано).

Обратите внимание, что вызов findViewById() несколько дорог, поэтому вам рекомендуется использовать "шаблон держателя вида", но вы уже используете тег view для чего-то другого.

...