我有一个用于GridView的自定义BaseAdapter。我在上面调用notifyDatasetChanged()。但是,未调用getView(),因此我的UI未更新。
我已经调试了这个并且看到底层数据是正确的,包含正确的启用状态,但是UI没有更新,因为没有调用getView()。
这是我的适配器:
public class MyAdapter extends BaseAdapter {
private List<? extends MyListItem> mItems;
protected Context mContext;
private LayoutInflater mInflater;
private int mLayout;
static class ItemView {
View mLayout;
ImageView mIcon;
TextView mCaption;
}
public MyAdapter(Context pContext, List<? extends MyListItem> items, int layout) {
mContext = pContext;
mItems = items;
mLayout = layout;
this.mInflater = LayoutInflater.from(pContext);
}
@Override
public int getCount() {
if (mItems == null)
return 0;
return mItems.size();
}
@Override
public MyListItem getItem(int position) {
if (mItems == null)
return null;
return mItems.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ItemView holder;
final MyListItem lItem = getItem(position);
if (convertView == null) {
holder = new ItemView();
convertView = mInflater.inflate(mLayout, null);
holder.mLayout = convertView.findViewById(R.id.LinearLayout1);
holder.mIcon = (ImageView) convertView.findViewById(R.id.imageView1);
holder.mCaption = (TextView) convertView.findViewById(R.id.textView1);
holder.mLayout.setEnabled(lItem.isEnabled());
holder.mCaption.setEnabled(lItem.isEnabled());
if (lItem.getIntent() != null) {
holder.mLayout.setClickable(true);
convertView.setOnClickListener(buildOnClickListener(lItem.getIntent()));
}
convertView.setTag(holder);
}
holder = (ItemView) convertView.getTag();
if (lItem != null) {
convertView.setVisibility(lItem.isVisible() ? View.VISIBLE : View.GONE);
holder.mIcon.setImageDrawable(lItem.getIcon(mContext));
holder.mCaption.setText(lItem.getCaption(mContext));
holder.mLayout.setEnabled(lItem.isEnabled());
holder.mCaption.setEnabled(lItem.isEnabled());
holder.mIcon.setEnabled(lItem.isEnabled());
holder.mLayout.setClickable(!lItem.isEnabled());
holder.mCaption.setClickable(!lItem.isEnabled());
holder.mIcon.setClickable(!lItem.isEnabled());
}
return convertView;
}
protected OnClickListener buildOnClickListener(final Intent pIntent) {
return new OnClickListener() {
@Override
public void onClick(View v) {
mContext.startActivity(pIntent);
}
};
}
public void invalidate() {
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
((MyPosition) buttonView.getTag()).setChecked(isChecked);
if (mListener != null) {
mListener.onItemsCheckChanged();
}
}
}
我在MyActivity中调用notifyDatasetChanged():
public class MyActivity extends Activity {
private MyAdapter mMyAdapter;
private GridView mMy_list;
private MyItem mButton;
mMyAdapter = new MyAdapter(this, myObjects.getMyItems(), R.layout.my_items);
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_activity, true);
}
public void setButtonEnabled(boolean enabled) {
mButton.setEnabled(enabled);
invalidateActionbar();
}
public void invalidateActionbar() {
refreshItems();
}
protected void refreshItems() {
mMyAdapter.notifyDataSetChanged();
}
public void setContentView(int id, boolean useScrollView) {
View mOverlayView = mGrid.init(this, mBaseView);
mMy_list = (GridView) findViewById(R.id.my_list);
mMy_list.setAdapter(mMyAdapter);
setContentView(mOverlayView);
}
}
触发所有这一切的checkChanged位于片段中:
public class MyFragment extends Fragment {
@Override
public void onItemsCheckChanged() {
final Activity activity = getActivity();
if (activity != null && activity instanceof MyActivity) {
final MyActivity myActivity = (MyActivity) getActivity();
if (myActivity != null) {
if (mAdapter != null) {
myActivity.setButtonEnabled(true);
}
}
}
}
}
public class MyItem {
private boolean mEnabled;
public void setEnabled(boolean enabled) {
this.mEnabled = enabled;
}
}
我迷失了为什么这不起作用。我怎样才能让它发挥作用?
在调用getView时,列表具有正确的数据,在某些情况下UI会刷新,但在其他情况下,不会调用getView。我需要触摸UI才能进行刷新。
编辑:
我也尝试过这种方法:
public void refresh(){
List<MyListItem> items= new ArrayList<MyListItem>(mItems);
mItems.clear();
notifyDataSetChanged();
mItems.addAll(items);
notifyDataSetChanged();
}
即使此代码运行,仍未调用getView()。
答案 0 :(得分:1)
更新你的setContentView,如下所示:
public void setContentView(int id, boolean useScrollView) {
setContentView(id);
mMy_list = (GridView) findViewById(R.id.my_list);
mMy_list.setAdapter(mMyAdapter);
}
答案 1 :(得分:0)
无论何时更改要传递给适配器并调用notifyDatasetChanged()的ArrayList的值,它都能正常工作。
MyList myList=myObjects.getMyItems();
MyAdapter mMyAdapter=new MyAdapter(this,myList); myList.add();
mMyAdapter.notifyDatasetChanged();
如果对arrayList的大小进行一些修改,则调用notifyDatasetChanged,请注意内部适配器构造函数,只需分配给引用,不要创建新的Object。
MyList myList;
MyAdapter(Context context,MyList myList)
{
this.myList=myList;
}
在您的代码中,请确保您在哪里更新列表,还要更新适配器。
其他方式 在适配器中创建一个函数,它将param作为列表,内部函数将其分配给适配器列表实例并执行notifyDatasetChanged。
/*Use this method instead where ever you are calling notifyDatasetChanged() directly*/
public void refereshData(List myList)
{
this.myList=myList;
notifyDatasetChanged()
}
将此功能称为
mAdapter.refereshData(list);