来自自定义适配器的Android notifyDataSetChanged

时间:2015-07-09 20:46:14

标签: android android-listview android-adapter baseadapter

所以我的应用程序通过contentProvider使用本地SQLite数据库 在它的mainActivity中,我有一个listView,显示上面数据库中表格的内容。

我使用自定义适配器来显示列表视图。每个项目都有一个按钮(自定义)布局,按下后,会显示一个自定义对话框,在该表中插入新记录,然后对话框被取消。 为了实现此行为,我将按钮单击处理程序放在customAdapter中。 我希望能够在插入完成后刷新listView(所以当对话框被解除时)

我怎样才能做到这一点? 我可能需要从自定义适配器内部以某种方式调用notifyDataSetChanged,但我不能。

简而言之,我的自定义适配器如下所示:

public class DisplayStuffAdapter extends BaseAdapter {
    private Context mContext;
    private ArrayList<String> id;
    private ArrayList<String> iduser;
    private ArrayList<String> product;


    public DisplayStuffAdapter(Context c){
        this.mContext = c;
    }

    public DisplayStuffAdapter(Context c,  ArrayList<String> id, ArrayList<String> userid, ArrayList<String> product) {
        this.mContext = c;
        this.id = id;
        this.userid = userid;
        this.product = product;
    }

 public int getCount() {
        return id.size();
    }

    public Object getItem(int position) {
        return null;
    }

    public long getItemId(int position) {
        return 0;
    }

    public class Holder {
        TextView txt_id;
        TextView txt_userid;
        TextView txt_prod;
    }


  public View getView(int pos, View child, ViewGroup parent) {
        Holder mHolder;
        LayoutInflater layoutInflater;
        if (child == null) {
            layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            child = layoutInflater.inflate(R.layout.myitem, null);
            mHolder = new Holder();
            mHolder.txt_id = (TextView) child.findViewById(R.id.tv_MkId);
            mHolder.txt_userid = (TextView) child.findViewById(R.id.tv_MkUserId);
            mHolder.txt_prod = (TextView) child.findViewById(R.id.tv_MkProduct);
            child.setTag(mHolder);
        } else {
            mHolder = (Holder) child.getTag();
        }
        mHolder.txt_id.setText(id.get(pos));
        mHolder.txt_userid.setText(userid.get(pos));
        mHolder.txt_prod.setText(product.get(pos));

     Button bt = (Button) child.findViewById(R.id.itemButton);
        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
              LayoutInflater li = LayoutInflater.from(mContext);
              final View promptsView = li.inflate(R.layout.bid_dialog, null);
              AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(mContext);
              alertDialogBuilder.setView(promptsView);
alertDialogBuilder.setMessage("Input data")
                 .setIcon(R.drawable.add_red_24)
                 .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    dialogInterface.dismiss();
                                }
                            })
                 .setPositiveButton("Add new record", new DialogInterface.OnClickListener() {
                     @Override
                     public void onClick(DialogInterface dialogInterface, int i) {
                 ContentValues values = new ContentValues();
                 values.put(MyProvider.TCOL_ID, myid);
                 values.put(MyProvider.TCOL_OTHERID, Integer.toString(getActiveUserId()));
                 Uri uri = mContext.getContentResolver().insert(MyProvider.CONTENT_URI_TABLE, values);
                 values = new ContentValues();
                 dialogInterface.dismiss();
                      }
                    }
                  }
               });

                // create alert dialog
                final AlertDialog alertDialog = alertDialogBuilder.create();
                // show it
                alertDialog.show();
                alertDialog.setCanceledOnTouchOutside(false);
....
        }
    });
....

我从代码中删除了一些部分,使其更具可读性。 现在,在我的MainActivity中,我将适配器设置为:

public class MainActivity extends Activity{
    private ArrayList<String> id = new ArrayList<String>();
    private ArrayList<String> userid = new ArrayList<String>();
    private ArrayList<String> product = new ArrayList<String>();
 ...
 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        fillListView();
    }
 ...

 private void fillListView(){
        id.clear();
        userid.clear();
        product.clear();

        String[] col = {MyProvider.TCOL_ID_ID, MyProvider.TCOL_USERID, MyProvider.TCOL_PROD};
        String where = "done = 1";
        Cursor mCursor =  MainActivity.this.getContentResolver().query(MyProvider.CONTENT_URI_TABLE, col, where, null, MyProvider.TCOL_DATE + " desc");
        if (mCursor != null) {
            if (mCursor.moveToFirst()) {
                do {
                    id.add(Integer.toString(mCursor.getInt(0)));
                    userid.add(Integer.toString(mCursor.getInt(1)));
                    product.add(mCursor.getString(2));
                } while (mCursor.moveToNext());
            }
        }

        DisplayStuffAdapter disadpt = new DisplayStuffAdapter(MainActivity.this,id,userid,product);
        disadpt.notifyDataSetChanged();
        ListView lv = (ListView) findViewById(R.id.mylistView);
        lv.setAdapter(disadpt);
    }

所以这一切都很有效,除了当我使用上面描述的customdialog向表中添加新记录时...对话框关闭,列表视图保持不变。

如何刷新listView?

2 个答案:

答案 0 :(得分:0)

public class DisplayStuffAdapter extends BaseAdapter {
    private Context mContext;
    private ArrayList<String> id;
    private ArrayList<String> iduser;
    private ArrayList<String> product;

    public DisplayStuffAdapter(Context c){
        this.mContext = c;
    }

    public void loadData(){
        id.clear();
        userid.clear();
        product.clear();

        String[] col = {MyProvider.TCOL_ID_ID, MyProvider.TCOL_USERID, MyProvider.TCOL_PROD};
        String where = "done = 1";
        Cursor mCursor =  MainActivity.this.getContentResolver().query(MyProvider.CONTENT_URI_TABLE, col, where, null, MyProvider.TCOL_DATE + " desc");
        if (mCursor != null) {
            if (mCursor.moveToFirst()) {
                do {
                    id.add(Integer.toString(mCursor.getInt(0)));
                    userid.add(Integer.toString(mCursor.getInt(1)));
                    product.add(mCursor.getString(2));
                } while (mCursor.moveToNext());
            }
        }
        notifyDataSetChanged();
    }
...
}

public class MainActivity extends Activity{
    private DisplayStuffAdapter disadpt = null;

    ContentObserver displayStuffObserver = new ContentObserver(new Handler()){  
        @Override
        public void onChange(boolean selfChange) {
            if(disadpt != null) {
                disadpt.loadData();
            }
        }       
    }

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        disadpt = new DisplayStuffAdapter(this);
        ListView lv = (ListView) findViewById(R.id.mylistView);
        lv.setAdapter(disadpt);
        disadpt.loadData();
           getContentResolver().registerContentObserver(MyProvider.CONTENT_URI_TABLE,true, displayStuffObserver);
    }
}

不要忘记取消注册您的内容观察者

答案 1 :(得分:0)

通常,当您从数据库查询数据时,应使用ContentProviderCursorLoader。您可以使用ContentResolver notifyChange()方法将内容提供程序配置为在某些数据发生更改时自动通知加载程序。在ContentProvider实现中调用此方法(例如在插入之后)。这是您可以使用的适配器示例(但您也可以使用SimpleCursorAdapter提供视图绑定器)。

public class CustomCursorAdapter extends CursorAdapter {

private LayoutInflater mInflater;

public CustomCursorAdapter(Context context, Cursor c, int flags) {
    super(context, c, flags);
    mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

@Override
public void bindView(View view, Context context, Cursor cursor) {

    if(cursor.getPosition()%2==1) {
        view.setBackgroundColor(context.getResources().getColor(R.color.background_odd));
    }
    else {
        view.setBackgroundColor(context.getResources().getColor(R.color.background_even));
    }
    TextView content = (TextView) view.findViewById(R.id.row_content);
    content.setText(cursor.getString(cursor.getColumnIndex(Table.CONTENT)));
}

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
    return mInflater.inflate(R.layout.listitem, parent, false);
}

}