我的自定义的CursorAdapter没有更新我的ListView [英] My Custom CursorAdapter doesn't update my ListView

查看:281
本文介绍了我的自定义的CursorAdapter没有更新我的ListView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有我的自定义的CursorAdapter 我的的ListView ,事实是,我可以将数据保存的烦恼我在我的自定义SQLite数据库的ContentProvider ,但我的的ListView 不填充。

我知道DB操作是沉重的长时间作业,因此我这样做是在另一个线程,进而 CursorLoader AsyncTaskLoader ,所以它应该是ppared为$ p $。

使用 SimpleCursorAdapter 工作正常,但与此自定义的CursorAdapter 不是

谁能告诉我什么是错的,我怎么能解决呢?

先谢谢了。

我的code是以下

 公共类TextNoteAdapter扩展的CursorAdapter {    / ***********声明中使用的变量********* /    私人光标mCursor;
    私人语境mContext;
    私有静态LayoutInflater mInflater = NULL;    / ************* TextNoteAdapter构造***************** /
    公共TextNoteAdapter(上下文的背景下,光标光标,INT标志){
        超(上下文,光标,标志);        mInflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mContext =背景;
        mCursor =光标;
    }    @覆盖
    公共查看NewView的(上下文的背景下,光标光标的ViewGroup父){        // LayoutInflater充气= LayoutInflater.from(parent.getContext());
        查看查看= mInflater.inflate(R.layout.textnote_info,父母,假);
        ViewHolder持有人=新ViewHolder();        holder.note_name =(TextView中)view.findViewById(R.id.note_name);
        holder.creation_date =(TextView中)view.findViewById(R.id.creation_date);
        holder.modification_date =(TextView中)view.findViewById(R.id.modification_date);
        holder.label_creation_date =(TextView中)view.findViewById(R.id.label_creation_date);
        holder.label_modification_date =(TextView中)view.findViewById(R.id.label_modification_date);
        view.setTag(保持器);        返回视图。
    }     @覆盖
     公共无效bindView(查看视图,上下文的背景下,光标光标){
         //这里我们设置我们的数据什么手段,从游标中取数据,并把它放在意见
         查看VI =视图。
         ViewHolder支架=(ViewHolder)view.getTag();         如果(查看== NULL){
             / ******充气的每一行textnote_info.xml文件(下面定义)******* /
             VI = mInflater.inflate(R.layout.textnote_info,NULL);            / ************组保持与LayoutInflater ************ /
             vi.setTag(保持器);         }其他
             支架=(ViewHolder)vi.getTag();
         / ************在保持元件集模型值*********** /
         holder.note_name.setText(cursor.getString(cursor.getColumnIndex(TextNotesDb.KEY_NOTE_NAME)));
         holder.creation_date.setText(cursor.getString(cursor.getColumnIndex(TextNotesDb.KEY_CREATION_DATE)));
         holder.modification_date.setText(cursor.getString(cursor.getColumnIndex(TextNotesDb.KEY_MODIFICATION_DATE)));
         holder.label_creation_date.setText(Constants.LABEL_CREATION_DATE);
         holder.label_modification_date.setText(Constants.LABEL_MODIFICATION_DATE);     }
     @覆盖
     保护无效onContentChanged(){
          // TODO自动生成方法存根
          super.onContentChanged();
          notifyDataSetChanged();
     }
     / *********创建一个holder类包含虚增XML文件中的元素********* /
     公共静态类ViewHolder {         公众的TextView note_name;
         公众的TextView CREATION_DATE;
         公众的TextView modification_date;
         公众的TextView label_creation_date;
         公众的TextView label_modification_date;     } }

在这里,我MainActivity

 进口android.app.Activity;
进口android.app.LoaderManager;
进口android.content.CursorLoader;
进口android.content.Intent;
进口android.content.Loader;
进口android.database.Cursor;
进口android.os.Bundle;
进口android.os.Handler;
进口android.util.Log;
进口android.view.Menu;
进口android.view.View;
进口android.widget.AdapterView;
进口android.widget.AdapterView.OnItemClickListener;
进口android.widget.Button;
进口android.widget.CursorAdapter;
进口android.widget.ListView;
进口android.widget.Toast;公共类MainActivity扩展活动实现LoaderManager.LoaderCallbacks<&光标GT; {
    私人光标指针;
    私人按钮Add按钮;
    私人的ListView ListView的;
    私人TextNoteAdapter DataAdapter的;
    @覆盖
    保护无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.activity_main);        displayListView();        Add按钮=(按钮)findViewById(R.id.add_textnote);        addButton.setOnClickListener(新View.OnClickListener(){            @覆盖
            公共无效的onClick(视图v){
                //开始一个新的意向添加注释
                意向意图=新意图(getBaseContext(),TextNoteEdit.class);
                束束=新包();
                bundle.putString(模式,添加);
                intent.putExtras(包);
                startActivity(意向);
            }
        });    }    @覆盖
    保护无效onResume(){
        super.onResume();
        Log.i(TAG,MainActivity :: onResume);
        / **开始一个新的或在这个管理器重新启动现有的装载机** /
        getLoaderManager()restartLoader(0,null,则此)。
    }
    私人无效displayListView(){    //这保证了加载器初始化和积极的。
    //如果由ID指定的加载器已经存在,最后创建的加载器重复使用。
    //别的initLoader()触发LoaderManager.LoaderCallbacks方法onCreateLoader()。
    //这是你实现了code实例,并返回一个新的Loader    getLoaderManager()initLoader(0,null,则此)。
    //我们从布局得到ListView和初始化
    ListView控件=(ListView控件)findViewById(R.id.textnote_list);    // DB需要很长,因此,该操作应在一个新的线程!
    新的处理程序()。后(新的Runnable(){
                @覆盖
                公共无效的run(){
                    DataAdapter的=新TextNoteAdapter(MainActivity.this,空,CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
                    listView.setAdapter(DataAdapter的);
                    Log.i(TAG,MainActivity ::处理程序...执行命令());
                }
            });    listView.setOnItemClickListener(新OnItemClickListener(){
            @覆盖
            公共无效onItemClick(适配器视图<>的ListView,观景,INT位置,长的id){                / **获取光标定位到相应的行中的结果集** /
                光标光标=(光标)listView.getItemAtPosition(位置);                //显示选中的音符
                串noteName = cursor.getString(cursor.getColumnIndexOrThrow(TextNotesDb.KEY_NOTE_NAME));                Toast.makeText(getApplicationContext(),noteName,Toast.LENGTH_SHORT).show();                字符串ROWID = cursor.getString(cursor.getColumnIndexOrThrow(TextNotesDb.KEY_ROWID));
                //开始一个新的意图更新/删除Textnote
                //传递的行ID创建内容的URI单行
                意向意图=新意图(getBaseContext(),TextNoteEdit.class);
                束束=新包();
                bundle.putString(模式,更新);
                bundle.putString(ROWID,ROWID);
                intent.putExtras(包);
                startActivityForResult(意向,1);            }
        });    }    / **这被称为当一个新的Loader需要创建。** /
    @覆盖
    公共装载机<&光标GT; onCreateLoader(INT ID,捆绑参数){
        Log.i(TAG,MainActivity :: onCreateLoader);
        的String [] =投影{
                            TextNotesDb.KEY_ROWID,
                            TextNotesDb.KEY_GUID,
                            TextNotesDb.KEY_NOTE_NAME,
                            TextNotesDb.KEY_NOTE,
                            TextNotesDb.KEY_CREATION_DATE,
                            TextNotesDb.KEY_MODIFICATION_DATE
                           };
     CursorLoader cursorLoader =新CursorLoader(这一点,MyContentProvider.CONTENT_URI,投影,NULL,NULL,NULL);        返回cursorLoader;
    }    @覆盖
    公共无效onLoadFinished(装载机<&光标GT;装载机,游标数据){
        //交换新的光标(该框架将采取关闭照顾
        //老光标一旦我们回来。)
        dataAdapter.swapCursor(数据);
    }    @覆盖
    公共无效onLoaderReset(装载机<&光标GT;装载机){
        //这就是所谓的当提供给onLoadFinished一个光标()
        //上述即将被关闭。我们需要确保我们没有
        //不再使用它。
        dataAdapter.swapCursor(NULL);
    }    @覆盖
    公共布尔onCreateOptionsMenu(菜单菜单){
        。getMenuInflater()膨胀(R.menu.activity_main,菜单);
        返回true;
    }
}


解决方案

正如下面我的问题的评论,我可以通过添加2行解决。现在它看起来应该是这样

  @覆盖
公共无效onLoadFinished(装载机<&光标GT;装载机,游标数据){
    //交换新的光标(该框架将采取关闭照顾
    //老光标一旦我们回来。)
    dataAdapter.notifyDataSetChanged(); //< -
    listView.setAdapter(DataAdapter的); //< -
    dataAdapter.swapCursor(数据);
}

I'm having troubles with my Custom CursorAdapter and my ListView, the fact is, I can save data in my sqlite Database in my custom ContentProvider but my ListView is not populated.

I know DB Operations are heavy long operations, therefore I do it in another thread and furthermore CursorLoader is a subclass of AsyncTaskLoader, so it should be prepared for that.

With SimpleCursorAdapter works fine but with this Custom CursorAdapter not.

Can anyone tell me what is wrong and how could I solve it?

Thanks in advance.

My code is the following

public class TextNoteAdapter extends CursorAdapter {

    /*********** Declare Used Variables *********/

    private Cursor                 mCursor;
    private Context                mContext;         
    private static  LayoutInflater mInflater=null;

    /*************  TextNoteAdapter Constructor *****************/
    public TextNoteAdapter (Context context, Cursor cursor, int flags) {
        super(context, cursor,flags);

        mInflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mContext  = context;
        mCursor   = cursor;                           
    } 

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {

        //LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View view = mInflater.inflate(R.layout.textnote_info, parent, false);
        ViewHolder holder = new ViewHolder();

        holder.note_name               = (TextView)view.findViewById(R.id.note_name);
        holder.creation_date           = (TextView)view.findViewById(R.id.creation_date);
        holder.modification_date       = (TextView)view.findViewById(R.id.modification_date);
        holder.label_creation_date     = (TextView)view.findViewById(R.id.label_creation_date);
        holder.label_modification_date = (TextView)view.findViewById(R.id.label_modification_date);


        view.setTag(holder);

        return view;
    }    

     @Override
     public void bindView(View view, Context context, Cursor cursor) {
         // here we are setting our data what means, take the data from the cursor and put it in views
         View vi = view;
         ViewHolder holder = (ViewHolder)view.getTag();

         if(view==null){                  
             /****** Inflate textnote_info.xml file for each row ( Defined below ) *******/
             vi = mInflater.inflate(R.layout.textnote_info, null);

            /************  Set holder with LayoutInflater ************/
             vi.setTag( holder );

         } else 
             holder=(ViewHolder)vi.getTag();                          


         /************  Set Model values in Holder elements ***********/
         holder.note_name.setText(cursor.getString(cursor.getColumnIndex(TextNotesDb.KEY_NOTE_NAME)));
         holder.creation_date.setText(cursor.getString(cursor.getColumnIndex(TextNotesDb.KEY_CREATION_DATE)));
         holder.modification_date.setText(cursor.getString(cursor.getColumnIndex(TextNotesDb.KEY_MODIFICATION_DATE)));
         holder.label_creation_date.setText(Constants.LABEL_CREATION_DATE);
         holder.label_modification_date.setText(Constants.LABEL_MODIFICATION_DATE);

     }         


     @Override
     protected void onContentChanged() {
          // TODO Auto-generated method stub
          super.onContentChanged();
          notifyDataSetChanged();
     }         


     /********* Create a holder Class to contain inflated xml file elements *********/
     public static class ViewHolder{

         public TextView note_name;
         public TextView creation_date;
         public TextView modification_date;
         public TextView label_creation_date;
         public TextView label_modification_date;

     }



 }

And here my MainActivity

import android.app.Activity;
import android.app.LoaderManager;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.Loader;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.CursorAdapter;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends Activity implements LoaderManager.LoaderCallbacks<Cursor>{


    private Cursor              cursor;
    private Button              addButton;
    private ListView            listView;
    private TextNoteAdapter     dataAdapter;


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

        displayListView(); 

        addButton = (Button)findViewById(R.id.add_textnote);

        addButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // starts a new Intent to add a Note
                Intent intent = new Intent(getBaseContext(), TextNoteEdit.class);
                Bundle bundle = new Bundle();
                bundle.putString("mode", "add");
                intent.putExtras(bundle);
                startActivity(intent);
            }
        });

    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.i("TAG", "MainActivity:: onResume");
        /** Starts a new or restarts an existing Loader in this manager **/
        getLoaderManager().restartLoader(0, null, this);
    }


    private void displayListView() {

    // That ensures a loader is initialized and active.
    // If the loader specified by the ID already exists, the last created loader is reused.
    // else  initLoader() triggers the LoaderManager.LoaderCallbacks method onCreateLoader().
    // This is where you implement the code to instantiate and return a new loader

    getLoaderManager().initLoader(0, null, this);        


    // We get ListView from Layout and initialize
    listView = (ListView) findViewById(R.id.textnote_list);

    // DB takes long, therefore this operation should take place in a new thread!                     
    new Handler().post(new Runnable() {
                @Override
                public void run() {
                    dataAdapter = new TextNoteAdapter(MainActivity.this, null, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
                    listView.setAdapter(dataAdapter);
                    Log.i("TAG", "MainActivity:: Handler... Run()");                       
                }
            });               

    listView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> listView, View view, int position, long id) {

                /** Get the cursor, positioned to the corresponding row in the result set **/
                Cursor cursor = (Cursor) listView.getItemAtPosition(position);               

                // display the selected note
                String noteName = cursor.getString(cursor.getColumnIndexOrThrow(TextNotesDb.KEY_NOTE_NAME));

                Toast.makeText(getApplicationContext(), noteName, Toast.LENGTH_SHORT).show();

                String rowId = cursor.getString(cursor.getColumnIndexOrThrow(TextNotesDb.KEY_ROWID));


                // starts a new Intent to update/delete a Textnote
                // pass in row Id to create the Content URI for a single row
                Intent intent = new Intent(getBaseContext(), TextNoteEdit.class);
                Bundle bundle = new Bundle();
                bundle.putString("mode", "update");
                bundle.putString("rowId", rowId);
                intent.putExtras(bundle);
                startActivityForResult(intent, 1);

            }
        });

    }    

    /** This is called when a new Loader needs to be created.**/
    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        Log.i("TAG", "MainActivity:: onCreateLoader");
        String[] projection = { 
                            TextNotesDb.KEY_ROWID,
                            TextNotesDb.KEY_GUID,
                            TextNotesDb.KEY_NOTE_NAME,
                            TextNotesDb.KEY_NOTE,
                            TextNotesDb.KEY_CREATION_DATE,
                            TextNotesDb.KEY_MODIFICATION_DATE
                           };
     CursorLoader cursorLoader = new CursorLoader(this, MyContentProvider.CONTENT_URI, projection, null, null, null);

        return cursorLoader;
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        // Swap the new cursor in.  (The framework will take care of closing the
        // old cursor once we return.)       
        dataAdapter.swapCursor(data);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        // This is called when the last Cursor provided to onLoadFinished()
        // above is about to be closed.  We need to make sure we are no
        // longer using it.
        dataAdapter.swapCursor(null);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }


}

解决方案

As in comment below my Question, I could solve it by adding 2 lines. Now it should look like this

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    // Swap the new cursor in.  (The framework will take care of closing the
    // old cursor once we return.)       
    dataAdapter.notifyDataSetChanged(); // <-
    listView.setAdapter(dataAdapter);   // <-
    dataAdapter.swapCursor(data);
}

这篇关于我的自定义的CursorAdapter没有更新我的ListView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆