2016-04-18 17 views
-1

GridViewで使用されるカスタムBaseAdapterがあります。私はnotifyDatasetChanged()を呼び出します。ただし、getView()は呼び出されないため、UIは更新されません。GridViewのBaseAdapter:notifyDatasetChanged()でgetView()が必ず呼び出されるとは限りません

これをデバッグし、getView()が呼び出されていないためUIが更新されませんが、基礎となるデータが正しい有効なステータスを含んでいることがわかりました。

これは私のアダプタです:

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に触れる必要があります。

EDIT:

Iはまた、この方法を試みた。)

public void refresh(){ 
    List<MyListItem> items= new ArrayList<MyListItem>(mItems); 
    mItems.clear(); 
    notifyDataSetChanged(); 
    mItems.addAll(items); 
    notifyDataSetChanged(); 
    } 

さらにgetViewメソッドは、(このコードが実行されていても呼び出されません。

+0

のように、この関数);'? –

+0

あなたのコードで 'notifyDatasetChanged();'を見ることができません。 –

+0

アクティビティにコールを追加しました – barq

答えて

1

更新以下のようにあなたのsetContentView:あなたは()アダプタに渡すとnotifyDatasetChangedを呼び出しているのArrayListの値を変更するたび

public void setContentView(int id, boolean useScrollView) { 
    setContentView(id); 
    mMy_list = (GridView) findViewById(R.id.my_list); 

    mMy_list.setAdapter(mMyAdapter); 

    } 
+0

私は既にidを持つsetContentViewを呼び出しています – barq

+0

私はあなたのコードでそれを見ていませんでした。 –

0

それは動作します。

MyList myList=myObjects.getMyItems(); 
MyAdapter mMyAdapter=new MyAdapter(this,myList); myList.add(); 
mMyAdapter.notifyDatasetChanged(); 

のArrayListのサイズでいくつかの変更が、その後notifyDatasetChangedを呼び出すと、アダプタのコンストラクタの内部で注意してくださいすることはあくまでも参考に割り当てた場合は、新しいオブジェクトを作成してはいけません。

MyList myList; 
MyAdapter(Context context,MyList myList) 
{ 
this.myList=myList; 
} 

あなたのコードでは、あなたがリストを更新する場所を確認してください。また、アダプタも更新してください。

その他の方法 paramをリストとし、関数内で関数をアダプタリストインスタンスに割り当て、notifyDatasetChangedを実行するアダプタ内に関数を1つ作成します。

/*Use this method instead where ever you are calling notifyDatasetChanged() directly*/ 
public void refereshData(List myList) 
{ 
this.myList=myList; 
notifyDatasetChanged() 
} 

コールあなたは `notifyDatasetChanged(と呼ばれる

mAdapter.refereshData(list); 
+0

ArrayListのサイズは変更されず、要素の1つのステータスだけが変更されます。これが問題だろうか? – barq

+0

項目が変更されているため、問題はありません。一部のプロパティが変更されています。notifyDatasetChanged()を呼び出します。同じ参照があり、それらの変更がリストにも反映されていることを確認してください。 – Godather

+0

変更がリストに反映されています。これはAndroidのバグです。ときどきリフレッシュされますが、時にはリフレッシュされません。 – barq

関連する問題