社会! 我需要帮助更新ListView中的不可见项。它不是项目内容,而是项目的视图表示。 好的,让我告诉你我的例子。我有一个字符串数组:
<string-array name="reminder_notifications">
<item>15 minutes before</item>
<item>30 minutes before</item>
<item>1 hour before</item>
<item>1.5 hour before</item>
<item>5 hours before</item>
<item>8 hours before</item>
<item>1 day before</item>
</string-array>
在Activity中我创建了适配器:
adapterNotifications = ArrayAdapter.createFromResource(this, R.array.reminder_notifications, R.layout.dialog_list_multiple_choise);
之后,我用一些方法计算出来自字符串数组的whitch项目可用于当前提醒。例如。如果用户在16:00设置16:45的提醒,则他只能选择项15 minutes before
和30 minutes before
。其他项目应禁用。
所以,谷歌之后我发现了如何在某个位置访问隐形ListView孩子:
public View getViewByPosition(int position, ListView listView) {
final int firstListItemPosition = listView.getFirstVisiblePosition();
final int lastListItemPosition = firstListItemPosition + listView.getChildCount() - 1;
if (position < firstListItemPosition || position > lastListItemPosition ) {
return listView.getAdapter().getView(position, listView.getChildAt(position), listView);
} else {
final int childIndex = position - firstListItemPosition;
return listView.getChildAt(childIndex);
}
}
现在,我正面临着最后一个问题(我希望) - 如何更新我从上面的方法获得的项目视图?我试着用这个:
View v = getViewByPosition(position, lvNotifications);
v.setEnabled(true);
但它只在第一次打开对话框后更新View,另外一个词我必须用ListView打开对话框窗口,关闭它并重新打开。只有在这种情况下,我才会得到更新的视图。 我知道,我的英文很糟糕所以下面有截图:
谢谢。
答案 0 :(得分:1)
你从错误的一面解决了这个问题。您不应该从适配器外部编辑视图,这是适配器的用途。相反,编写自己的适配器。这样做:
import android.content.Context;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;
/**
* A {@link ArrayAdapter} to let the user select multiple notification times.
*/
public class ReminderNotificationsAdapter extends BaseAdapter implements CompoundButton.OnCheckedChangeListener {
/**
* A array with all currently selected entries
*/
private boolean[] mSelected;
/**
* A array with all enabled entries
*/
private boolean[] mEnabled;
/**
* The items to be shown
*/
private String[] mItems;
/**
* A {@link Context}
*/
private Context mContext;
/**
* Creates a new instance
*
* @param context a {@link Context}
* @param items all selectable items
* @param checkedItems all selected items. This array will be updated with the users selectiion
* @param enabledItems all enabled items
*/
public ReminderNotificationsAdapter(Context context, String[] items, boolean[] checkedItems, boolean[] enabledItems) {
// Check array sizes
if(items.length != checkedItems.length || checkedItems.length != enabledItems.length) {
throw new RuntimeException("All arrays must be the same size");
}
// Add all and store params
this.mContext = context;
this.mItems = items;
this.mSelected = checkedItems;
this.mEnabled = enabledItems;
}
@Override
public int getCount() {
return this.mItems.length;
}
@Override
public String getItem(int i) {
return this.mItems[i];
}
@Override
public long getItemId(int i) {
return this.getItem(i).hashCode();
}
@NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
// Create view if not provided to convert
if(v == null) {
v = LayoutInflater.from(this.mContext).inflate(R.layout.dialog_list_multiple_choise, parent, false);
}
// Prepare text view
TextView tv = (TextView) v.findViewById(android.R.id.text1);
tv.setText(this.getItem(position));
tv.setEnabled(this.isEnabled(position));
// Prepare checkbox
CheckBox cb = (CheckBox) v.findViewById(android.R.id.checkbox);
cb.setTag(position);
cb.setChecked(this.mSelected[position]);
cb.setEnabled(this.isEnabled(position));
cb.setOnCheckedChangeListener(this);
// Return view
return v;
}
@Override
public boolean isEnabled(int position) {
return this.mEnabled[position];
}
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
this.mSelected[(Integer) compoundButton.getTag()] = b;
}
}
并像这样使用它:
@Override
public void onClick(View view) {
// Tell what string should be shown
String[] entries = this.getResources().getStringArray(R.array.reminder_notifications);
// Tell what entries should be already selected
final boolean[] selectedEntries = new boolean[entries.length];
selectedEntries[2] = true;
// Tell what entries should be enabled
boolean[] enabledEntries = new boolean[entries.length];
enabledEntries[0] = true;
enabledEntries[1] = true;
enabledEntries[2] = true;
enabledEntries[3] = true;
// Create the adapter
ReminderNotificationsAdapter a = new ReminderNotificationsAdapter(this, entries, selectedEntries, enabledEntries);
// Create and show the dialog
new AlertDialog.Builder(this)
.setTitle("Add notification")
.setAdapter(a, null)
.setPositiveButton("Set", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// Do what you want to do with the selected entries
Toast.makeText(MainActivity.this, Arrays.toString(selectedEntries), Toast.LENGTH_SHORT).show();
}
})
.setNegativeButton("Dismiss", null)
.show();
}
我只是使用一个布尔数组来告诉应该启用和选择哪些条目,如果你愿意,可以在那里做一些更优雅的事情。在提供给适配器构造函数的数组中更新用户的选择。 AlertDialog看起来像这样:
请参阅完整的示例应用here。