我有一個ExpandableListView。每個孩子都有一個CheckBox和一個TextView。當用戶點擊一個子行時,CheckBox應該改變其狀態(選中或未選中)。如果用戶直接點擊複選框,此功能將正常工作。但是,如果用戶點擊文本視圖(同一行,緊挨着複選框的右側),只要嘗試引用複選框,就會收到空指針錯誤。任何人都可以看到什麼是錯的?Android ExpandableListView在哪裏放置onClickListener
編輯:在閱讀下面的建議後,我做了一些調查,並意識到我可以在getChildView()我的適配器內實現我的clickListener。這解決了我對空指針的問題,因爲我可以很容易地獲得對子視圖的引用。
但是,它造成了另一個問題,我看不到優雅的解決方案。每次點擊一個孩子時,我需要對列表視圖本身進行更改。此列表的數據位於範圍在Activity內的ArrayList中(不在Adapter中)。如果我的clickListener在適配器中,我怎樣才能回調活動來修改ArrayList?
這讓我覺得自己是個22號。如果我想能夠操縱我的數據,我無法獲得對子視圖的引用。但是如果我想引用我的子視圖,我的數據超出了範圍,所以我不能操縱它。人們如何解決這個問題?我肯定錯過了什麼。
我會拋出相關的適配器代碼,您可以在其中看到我嘗試添加onClickListener子項的開始。
再次感謝!
public class Settings extends Activity {
//this is the list I need to access from the adapter if my click listener is there
private ArrayList<Categories> categoriesList = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_smart_settings);
db = new EventsDB(this);
expListGroups = new ArrayList<ExpandListGroup>();
setGroups();
/* Set up the data adapter */
expAdapter = new ExpandListAdapter(Settings.this, expListGroups);
populateExpandableGroups();
}
public void setGroups() {
/* Create lists of the individual line items */
categoriesList = db.getCategoriesForClient(client);
locationsList = db.getLocationsForClient(client);
/* Add an item to the locations list to allow the user to add a new location */
locationsList.add(new ClientSmartFinderLocations(client, "Add Location", null, false));
ExpandListGroup categoryGroup = new ExpandListCategory("Choose Categories", categoriesList);
ExpandListGroup locationGroup = new ExpandListLocation("Choose Locations", locationsList);
expListGroups.add(categoryGroup);
expListGroups.add(locationGroup);
}
private void populateExpandableGroups() {
expandableList = (ExpandableListView) findViewById(R.id.expandable_list);
expandableList.setAdapter(expAdapter);
//I've removed this section and moved it to the adapter, per my edit above
// expandableList.setOnChildClickListener(new OnChildClickListener() {
//
// @Override
// public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
//
// /* Update the finder setting for this client */
// String category = categoriesList.get(childPosition).getCategory();
// Boolean isSelected = !categoriesList.get(childPosition).getIsSelected();
// db.setClientCategory(client, category, isSelected);
//
// /* Update the check box to provide feedback to the user */
// View view = parent.getChildAt(childPosition - parent.getFirstVisiblePosition() + 1);
// CheckBox checkBox = (CheckBox) view.findViewById(R.id.check_box);
//
// //error occurs here
// checkBox.setChecked(!checkBox.isChecked());
// return true;
// }
// });
expAdapter.notifyDataSetChanged();
}
public class ExpandListAdapter extends BaseExpandableListAdapter {
//other methods
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View view, final ViewGroup parent) {
view = getCategoryChildView(groupPosition, childPosition, view);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
TextView tv = (TextView) v.findViewById(R.id.expand_list_item);
CheckBox checkBox = (CheckBox) v.findViewById(R.id.check_box);
String category = tv.getText().toString();
Boolean isSelected = !checkBox.isSelected();
db = new EventsDB(context);
db.setClientCategory(client, category, isSelected);
checkBox.setChecked(!checkBox.isChecked());
//here I need to do some things that require me to manipulate the categoriesList from the Activity class - but it is out of scope
}
});
return view;
}
}
<CheckBox
android:id="@+id/check_box"
android:layout_marginLeft="30dp"
android:focusable="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/expand_list_item"
android:paddingLeft="10dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="@dimen/smart_finder_settings_font_size"
android:textColor="#FFFFFF" />
謝謝。我確實在適配器內設置了複選框的初始狀態。這裏我正在嘗試處理onChildClick事件。除了切換複選框的狀態之外,在解決空指針問題之後還需要執行其他處理。你是否說我應該在適配器內部進行此操作?我會在適配器中做什麼?再次感謝! – Alex