点击GridView按钮更新ListView内容的安卓开发问题求助
解决GridView按钮点击更新ListView的问题
看起来你遇到的核心问题是:独立的ArtiklBtnOnClickListener类无法访问BlagajnaActivity中的列表数据和ListView适配器,导致点击按钮后没法更新ListView的显示。下面是具体的解决思路和修改后的代码:
关键问题分析
- 你的点击事件类是独立的,无法直接操作Activity里的
racunList和racun_adapter - 目前点击按钮后只是查询了数据库,没有把数据添加到列表,也没有通知适配器刷新
- 从按钮文本中解析商品信息的方式容易出错,不如直接复用已有的
ArtiklData对象
具体解决方案
步骤1:将点击事件改为Activity内部类
让ArtiklBtnOnClickListener成为BlagajnaActivity的内部类,这样它就能直接访问Activity的成员变量(比如racunList和racun_adapter)。同时把racun_adapter提升为Activity的成员变量,避免被局部作用域限制。
步骤2:直接传递ArtiklData对象到点击事件
在GridView的getView方法中,直接把当前位置的ArtiklData对象传给点击事件,不用再从按钮文本解析数据,也不用重复查询数据库,既高效又可靠。
步骤3:点击时更新列表并通知适配器
在点击事件中,把选中的商品数据添加到racunList,然后调用适配器的notifyDataSetChanged()方法触发ListView刷新。
修改后的完整代码片段
public class BlagajnaActivity extends AppCompatActivity { GridView myBtngridView; ListView racunListView; ArrayList racunList = new ArrayList<>(); // 将适配器改为成员变量,让内部类可访问 RacunListViewAdapter racun_adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setTitle("Blagajna"); setContentView(R.layout.activity_blagajna); DatabaseHelper database = new DatabaseHelper(this); SQLiteDatabase db = database.getReadableDatabase(); String[] projection = { ArtiklData.ArtiklDescription._ID, ArtiklData.ArtiklDescription.ARTIKL, ArtiklData.ArtiklDescription.KOLICINA_NA_SKLADISTU, ArtiklData.ArtiklDescription.CIJENA, ArtiklData.ArtiklDescription.TIP }; String sortOrder = ArtiklData.ArtiklDescription.ARTIKL + " ASC"; Cursor cursor = db.query( ArtiklData.ArtiklDescription.TABLE_NAME, projection, null, null, null, null, sortOrder ); // 初始化适配器为成员变量 racun_adapter = new RacunListViewAdapter(this, R.layout.racun_layout, racunList); racunListView = findViewById(R.id.LV_Racun); racunListView.setAdapter(racun_adapter); ArrayList<ArtiklData> artiklNamesList = new ArrayList<>(); while (cursor.moveToNext()) { String artikl = cursor.getString(cursor.getColumnIndexOrThrow(ArtiklData.ArtiklDescription.ARTIKL)); Integer kolicina = cursor.getInt(cursor.getColumnIndexOrThrow(ArtiklData.ArtiklDescription.KOLICINA_NA_SKLADISTU)); Integer cijena = cursor.getInt(cursor.getColumnIndexOrThrow(ArtiklData.ArtiklDescription.CIJENA)); Boolean tip = cursor.getInt(cursor.getColumnIndexOrThrow(ArtiklData.ArtiklDescription.TIP)) == 1; artiklNamesList.add(new ArtiklData(artikl, kolicina, cijena, tip)); } CustGridViewAdapter adapter_btn = new CustGridViewAdapter(this, artiklNamesList); myBtngridView = findViewById(R.id.GV_Artikli); myBtngridView.setAdapter(adapter_btn); cursor.close(); db.close(); } public class CustGridViewAdapter extends BaseAdapter { private Context mContext; private ArrayList<ArtiklData> artikli; public CustGridViewAdapter(Context context, ArrayList<ArtiklData> list) { this.mContext = context; this.artikli = list; } @Override public int getCount() { return artikli.size(); } @Override public Object getItem(int position) { return artikli.get(position); // 返回正确的ArtiklData对象,之前返回null是错误的 } @Override public long getItemId(int position) { return position; } @NonNull @Override public View getView(int position, View convertView, ViewGroup parent) { Button btn; ArtiklData artikl = artikli.get(position); if (convertView == null) { btn = new Button(mContext); btn.setLayoutParams(new GridView.LayoutParams(85, 85)); ViewGroup.LayoutParams p = btn.getLayoutParams(); p.width = ViewGroup.LayoutParams.WRAP_CONTENT; btn.setLayoutParams(p); btn.setPadding(8, 8, 8, 8); } else { btn = (Button) convertView; } String buttonText = String.format("%s\n\n%d Kn", artikl.getArtikl().toUpperCase(), artikl.getCijena()); btn.setText(buttonText); btn.setTransformationMethod(null); btn.setTextColor(Color.WHITE); btn.setOnClickListener(new ArtiklBtnOnClickListener(artikl)); return btn; } } // 改为Activity内部类,直接访问成员变量 public class ArtiklBtnOnClickListener implements View.OnClickListener { private final ArtiklData selectedArtikl; public ArtiklBtnOnClickListener(ArtiklData artikl) { this.selectedArtikl = artikl; } @Override public void onClick(View view) { // 将选中的商品添加到订单列表 racunList.add(selectedArtikl); // 通知适配器数据更新,ListView自动刷新 racun_adapter.notifyDataSetChanged(); // 如果你的ListView需要的是自定义订单项(而非ArtiklData),请转换后再添加: // racunList.add(new RacunItem(selectedArtikl.getArtikl(), selectedArtikl.getCijena())); } } }
额外说明
- 如果你的
RacunListViewAdapter适配的不是ArtiklData类型,而是自定义的订单条目类,只需要把selectedArtikl转换成对应的对象再添加到racunList即可。 - 移除了重复的数据库查询操作,直接复用GridView加载时已经获取的
ArtiklData对象,提升了性能。
内容的提问来源于stack exchange,提问作者jack_oneal
相关产品推荐
相关产品推荐

