问题描述
我有我的自定义的CursorAdapter
我的的ListView
,事实是,我可以将数据保存的烦恼我在我的自定义SQLite数据库的ContentProvider
,但我的的ListView
不填充。
我知道DB操作是沉重的长时间作业,因此我这样做是在另一个线程,进而 CursorLoader
是 AsyncTaskLoader $ C的子类$ C>,所以它应该是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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!