如何从 ListView 中的视图访问适配器对象
How to access an Adapter object from a View in the ListView
很长一段时间后我要回到 Android,但我遇到了一些问题。
该应用程序包含一个布局列表,每个布局都通过适配器由一个模型支持。
每个布局都有几个视图,其中一个是 Spinner。
想在改变Spinner的值时修改Adapter中的数据,但不知道如何引用Adapter中的对象
public class MainActivity extends AppCompatActivity {
ArrayList<Troop> values = new ArrayList<Troop>();
MySimpleArrayAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
values.add(new Troop());
final ListView listView =(ListView) findViewById(R.id.listview);
adapter = new MySimpleArrayAdapter(
this,
values);
listView.setAdapter(adapter);
}
public class Troop {
private String weapon;
private int bs;
private int total_modifier;
public Troop() {
}
public int getBs() {
return bs;
}
public void setBs(int bs) {
this.bs = bs;
}
}
public class MySimpleArrayAdapter extends ArrayAdapter {
private final Context context;
private ArrayList<Troop> troopers;
private String[] possible_bs = new String[] {"10", "11", "12", "13", "15", "16"};
public MySimpleArrayAdapter(Context context, ArrayList<Troop> values) {
super(context, -1, values);
this.context = context;
this.troopers = values;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.rowlayout, parent, false);
Spinner bs_spinner = rowView.findViewById(R.id.bs_spinner);
ArrayAdapter<String> bs_adapter = new ArrayAdapter<String>(
context,
android.R.layout.simple_spinner_dropdown_item,
possible_bs);
bs_spinner.setOnItemSelectedListener(new CustomOnItemSelectedListener());
bs_spinner.setAdapter(bs_adapter);
return rowView;
}
}
public class CustomOnItemSelectedListener implements AdapterView.OnItemSelectedListener {
public void onItemSelected(AdapterView<?> parent, View view, int pos,long id) {
// I want to call getBs on the Trooper correspoding to this view here
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
}
}
这里有很多我要解决的问题。首先,让我们谈谈您的 ArrayAdapter
子类。
如您问题的评论中所述,您应该将其更改为 extends ArrayAdapter<Troop>
。这将导致 getItem()
变为 return Troop
而不是 Object
.
您无需存储自己的 context
或 troopers
字段。基本 ArrayAdapter
实现在 mContext
字段中存储了一个上下文,您可以通过 getContext()
访问它。此外,它将支持数据存储在 mObjects
字段中,您可以通过 getItem()
.
访问它
最后,如果您的适配器中的所有项目都将共享相同的 possible_bs
值,您应该将其设为常量。
接下来说说AdapterView.OnItemSelectedListener
.
您需要一种方法来了解您的 Spinner
所在的位置(从您的 MySimpleArrayAdapter
)(相对于项目 内部 [=49= 的位置) ] Spinner
用户已选择)。我建议将此位置传递给构造函数并将其保存为私有最终字段。
要从 Spinner
内部获取适配器,您可以通过调用 parent.getAdapter()
访问支持 AdapterView
参数的 Adapter
,然后将其转换为您的想要的类型。
总的来说,你还剩下这个:
public static class MySimpleArrayAdapter extends ArrayAdapter {
private static final String[] POSSIBLE_BS = new String[] {"10", "11", "12", "13", "15", "16"};
public MySimpleArrayAdapter(Context context, ArrayList<Troop> values) {
super(context, -1, values);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.rowlayout, parent, false);
Spinner bs_spinner = rowView.findViewById(R.id.bs_spinner);
ArrayAdapter<String> bs_adapter = new ArrayAdapter<>(
getContext(),
android.R.layout.simple_spinner_dropdown_item,
POSSIBLE_BS);
bs_spinner.setOnItemSelectedListener(new CustomOnItemSelectedListener(position));
bs_spinner.setAdapter(bs_adapter);
return rowView;
}
}
private static class CustomOnItemSelectedListener implements AdapterView.OnItemSelectedListener {
private final int troopPosition;
private CustomOnItemSelectedListener(int troopPosition) {
this.troopPosition = troopPosition;
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
MySimpleArrayAdapter adapter = (MySimpleArrayAdapter) parent.getAdapter();
int bs = adapter.getItem(troopPosition).getBs();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
}
您可以匿名移动class。
如果您想要当前 ListView 元素以及内部适配器位置,则需要同时获取两个位置元素。
可能有更简洁的方法来做到这一点,但这是我的第一个想法
public class MySimpleArrayAdapter extends ArrayAdapter<Troop> {
private final Context context;
private ArrayList<Troop> troopers;
private String[] possible_bs = new String[] {"10", "11", "12", "13", "15", "16"};
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.rowlayout, parent, false);
Spinner bs_spinner = rowView.findViewById(R.id.bs_spinner);
final ArrayAdapter<String> bs_adapter = new ArrayAdapter<String>(
context,
android.R.layout.simple_spinner_dropdown_item,
possible_bs);
bs_spinner.setAdapter(bs_adapter);
bs_spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
// You can access MySimpleArrayAdapter.this or bs_adapter
Troop t = troopers.get(position); // or getItem(position);
String bs = possible_bs[pos];
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
return rowView;
}
很长一段时间后我要回到 Android,但我遇到了一些问题。
该应用程序包含一个布局列表,每个布局都通过适配器由一个模型支持。
每个布局都有几个视图,其中一个是 Spinner。
想在改变Spinner的值时修改Adapter中的数据,但不知道如何引用Adapter中的对象
public class MainActivity extends AppCompatActivity {
ArrayList<Troop> values = new ArrayList<Troop>();
MySimpleArrayAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
values.add(new Troop());
final ListView listView =(ListView) findViewById(R.id.listview);
adapter = new MySimpleArrayAdapter(
this,
values);
listView.setAdapter(adapter);
}
public class Troop {
private String weapon;
private int bs;
private int total_modifier;
public Troop() {
}
public int getBs() {
return bs;
}
public void setBs(int bs) {
this.bs = bs;
}
}
public class MySimpleArrayAdapter extends ArrayAdapter {
private final Context context;
private ArrayList<Troop> troopers;
private String[] possible_bs = new String[] {"10", "11", "12", "13", "15", "16"};
public MySimpleArrayAdapter(Context context, ArrayList<Troop> values) {
super(context, -1, values);
this.context = context;
this.troopers = values;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.rowlayout, parent, false);
Spinner bs_spinner = rowView.findViewById(R.id.bs_spinner);
ArrayAdapter<String> bs_adapter = new ArrayAdapter<String>(
context,
android.R.layout.simple_spinner_dropdown_item,
possible_bs);
bs_spinner.setOnItemSelectedListener(new CustomOnItemSelectedListener());
bs_spinner.setAdapter(bs_adapter);
return rowView;
}
}
public class CustomOnItemSelectedListener implements AdapterView.OnItemSelectedListener {
public void onItemSelected(AdapterView<?> parent, View view, int pos,long id) {
// I want to call getBs on the Trooper correspoding to this view here
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
}
}
这里有很多我要解决的问题。首先,让我们谈谈您的 ArrayAdapter
子类。
如您问题的评论中所述,您应该将其更改为 extends ArrayAdapter<Troop>
。这将导致 getItem()
变为 return Troop
而不是 Object
.
您无需存储自己的 context
或 troopers
字段。基本 ArrayAdapter
实现在 mContext
字段中存储了一个上下文,您可以通过 getContext()
访问它。此外,它将支持数据存储在 mObjects
字段中,您可以通过 getItem()
.
最后,如果您的适配器中的所有项目都将共享相同的 possible_bs
值,您应该将其设为常量。
接下来说说AdapterView.OnItemSelectedListener
.
您需要一种方法来了解您的 Spinner
所在的位置(从您的 MySimpleArrayAdapter
)(相对于项目 内部 [=49= 的位置) ] Spinner
用户已选择)。我建议将此位置传递给构造函数并将其保存为私有最终字段。
要从 Spinner
内部获取适配器,您可以通过调用 parent.getAdapter()
访问支持 AdapterView
参数的 Adapter
,然后将其转换为您的想要的类型。
总的来说,你还剩下这个:
public static class MySimpleArrayAdapter extends ArrayAdapter {
private static final String[] POSSIBLE_BS = new String[] {"10", "11", "12", "13", "15", "16"};
public MySimpleArrayAdapter(Context context, ArrayList<Troop> values) {
super(context, -1, values);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.rowlayout, parent, false);
Spinner bs_spinner = rowView.findViewById(R.id.bs_spinner);
ArrayAdapter<String> bs_adapter = new ArrayAdapter<>(
getContext(),
android.R.layout.simple_spinner_dropdown_item,
POSSIBLE_BS);
bs_spinner.setOnItemSelectedListener(new CustomOnItemSelectedListener(position));
bs_spinner.setAdapter(bs_adapter);
return rowView;
}
}
private static class CustomOnItemSelectedListener implements AdapterView.OnItemSelectedListener {
private final int troopPosition;
private CustomOnItemSelectedListener(int troopPosition) {
this.troopPosition = troopPosition;
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
MySimpleArrayAdapter adapter = (MySimpleArrayAdapter) parent.getAdapter();
int bs = adapter.getItem(troopPosition).getBs();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
}
您可以匿名移动class。
如果您想要当前 ListView 元素以及内部适配器位置,则需要同时获取两个位置元素。
可能有更简洁的方法来做到这一点,但这是我的第一个想法
public class MySimpleArrayAdapter extends ArrayAdapter<Troop> {
private final Context context;
private ArrayList<Troop> troopers;
private String[] possible_bs = new String[] {"10", "11", "12", "13", "15", "16"};
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.rowlayout, parent, false);
Spinner bs_spinner = rowView.findViewById(R.id.bs_spinner);
final ArrayAdapter<String> bs_adapter = new ArrayAdapter<String>(
context,
android.R.layout.simple_spinner_dropdown_item,
possible_bs);
bs_spinner.setAdapter(bs_adapter);
bs_spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
// You can access MySimpleArrayAdapter.this or bs_adapter
Troop t = troopers.get(position); // or getItem(position);
String bs = possible_bs[pos];
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
return rowView;
}