Mam więc niestandardowy obiekt ListView. Elementy listy mają dwa widoki tekstu ułożone jeden na drugim oraz poziomy pasek postępu, który chcę pozostać ukryty, dopóki coś nie zrobię. Po prawej stronie znajduje się pole wyboru, które chcę wyświetlać tylko wtedy, gdy użytkownik musi pobrać aktualizacje do swoich baz danych. Kiedy wyłączam to pole wyboru, ustawiając widoczność na Widoczność.GONE, mogę klikać elementy listy. Gdy pole wyboru jest widoczne, nie mogę kliknąć niczego na liście poza polami wyboru. Wyszukałem trochę, ale nie znalazłem nic związanego z moją obecną sytuacją. Znalazłem to pytanieale używam przesłoniętego ArrayAdapter, ponieważ używam ArrayLists do wewnętrznego przechowywania listy baz danych. Czy muszę tylko pobrać widok LinearLayout i dodać onClickListener, tak jak zrobił to Tom? Nie jestem pewny.
Oto XML układu wiersza widoku listy:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:padding="6dip">
<LinearLayout
android:orientation="vertical"
android:layout_width="0dip"
android:layout_weight="1"
android:layout_height="fill_parent">
<TextView
android:id="@+id/UpdateNameText"
android:layout_width="wrap_content"
android:layout_height="0dip"
android:layout_weight="1"
android:textSize="18sp"
android:gravity="center_vertical"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:id="@+id/UpdateStatusText"
android:singleLine="true"
android:ellipsize="marquee"
/>
<ProgressBar android:id="@+id/UpdateProgress"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:indeterminateOnly="false"
android:progressDrawable="@android:drawable/progress_horizontal"
android:indeterminateDrawable="@android:drawable/progress_indeterminate_horizontal"
android:minHeight="10dip"
android:maxHeight="10dip"
/>
</LinearLayout>
<CheckBox android:text=""
android:id="@+id/UpdateCheckBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
A oto klasa, która rozszerza ListActivity. Oczywiście wciąż jest w fazie rozwoju, więc wybacz rzeczy, których brakuje lub które mogą zostać:
public class UpdateActivity extends ListActivity {
AccountManager lookupDb;
boolean allSelected;
UpdateListAdapter list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
lookupDb = new AccountManager(this);
lookupDb.loadUpdates();
setContentView(R.layout.update);
allSelected = false;
list = new UpdateListAdapter(this, R.layout.update_row, lookupDb.getUpdateItems());
setListAdapter(list);
Button btnEnterRegCode = (Button)findViewById(R.id.btnUpdateRegister);
btnEnterRegCode.setVisibility(View.GONE);
Button btnSelectAll = (Button)findViewById(R.id.btnSelectAll);
btnSelectAll.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
allSelected = !allSelected;
for(int i=0; i < lookupDb.getUpdateItems().size(); i++) {
lookupDb.getUpdateItem(i).setSelected(!lookupDb.getUpdateItem(i).isSelected());
}
list.notifyDataSetChanged();
// loop through each UpdateItem and set the selected attribute to the inverse
} // end onClick
}); // end setOnClickListener
Button btnUpdate = (Button)findViewById(R.id.btnUpdate);
btnUpdate.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
} // end onClick
}); // end setOnClickListener
lookupDb.close();
} // end onCreate
@Override
protected void onDestroy() {
super.onDestroy();
for (UpdateItem item : lookupDb.getUpdateItems()) {
item.getDatabase().close();
}
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
UpdateItem item = lookupDb.getUpdateItem(position);
if (item != null) {
item.setSelected(!item.isSelected());
list.notifyDataSetChanged();
}
}
private class UpdateListAdapter extends ArrayAdapter<UpdateItem> {
private List<UpdateItem> items;
public UpdateListAdapter(Context context, int textViewResourceId, List<UpdateItem> items) {
super(context, textViewResourceId, items);
this.items = items;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = null;
if (convertView == null) {
LayoutInflater li = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = li.inflate(R.layout.update_row, null);
} else {
row = convertView;
}
UpdateItem item = items.get(position);
if (item != null) {
TextView upper = (TextView)row.findViewById(R.id.UpdateNameText);
TextView lower = (TextView)row.findViewById(R.id.UpdateStatusText);
CheckBox cb = (CheckBox)row.findViewById(R.id.UpdateCheckBox);
upper.setText(item.getName());
lower.setText(item.getStatusText());
if (item.getStatusCode() == UpdateItem.UP_TO_DATE) {
cb.setVisibility(View.GONE);
} else {
cb.setVisibility(View.VISIBLE);
cb.setChecked(item.isSelected());
}
ProgressBar pb = (ProgressBar)row.findViewById(R.id.UpdateProgress);
pb.setVisibility(View.GONE);
}
return row;
}
} // end inner class UpdateListAdapter
}
edycja: nadal mam ten problem. Oszukuję i dodaję moduły obsługi onClick do textviews, ale wydaje mi się bardzo głupie, że moja funkcja onListItemClick () nie jest w ogóle wywoływana, gdy nie klikam swojego pola wyboru.
źródło
Jeśli masz ImageButton wewnątrz elementu listy, powinieneś ustawić
descendantFocusability
wartość na 'blocksDescendants' w głównym elemencie listy.I
focusableInTouchMode
flagatrue
wImageButton
widoku.źródło
Miałem podobny problem i stwierdziłem, że CheckBox jest raczej wybredny w ListView. Co się dzieje, narzuca to na cały ListItem i w pewnym sensie zastępuje onListItemClick. Możesz chcieć zaimplementować w tym celu procedurę obsługi kliknięcia i ustawić właściwość text również dla CheckBox, zamiast używać TextViews.
Powiedziałbym, że spójrz również na ten obiekt View, może działać lepiej niż CheckBox
Sprawdzony widok tekstu
źródło
użyj tej linii w widoku głównym elementu listy
android: descendantFocusability = "blocksDescendants"
źródło