Android 使用光标适配器和加载程序时动态编辑列表视图项
我正在编写一个小型的消息应用程序,最近遇到了这个问题 我有一个Android 使用光标适配器和加载程序时动态编辑列表视图项,android,android-listview,android-cursoradapter,android-cursorloader,Android,Android Listview,Android Cursoradapter,Android Cursorloader,我正在编写一个小型的消息应用程序,最近遇到了这个问题 我有一个ListFragment子类,它实现了CursorLoader回调。内置的列表视图绑定到SimpleCorsorAdapter。此列表中的每个行视图都有一个可绘制为背景的级别。我想根据数据库信息(无论消息是否发送)在级别之间切换 我的问题是,在这种情况下,如何更改单行的背景?我必须通过适配器访问它吗?我很确定这应该在onLoadFinished方法中完成。但是这段代码给了我NullPointerException。如果你能给我指出正确
ListFragment
子类,它实现了CursorLoader
回调。内置的列表视图
绑定到SimpleCorsorAdapter
。此列表中的每个行视图都有一个可绘制为背景的级别。我想根据数据库信息(无论消息是否发送)在级别之间切换
我的问题是,在这种情况下,如何更改单行的背景?我必须通过适配器访问它吗?我很确定这应该在onLoadFinished
方法中完成。但是这段代码给了我NullPointerException
。如果你能给我指出正确的方向,我将非常感激
public class MessagesFragment extends ListFragment implements
LoaderManager.LoaderCallbacks<Cursor>{
private static MessagesFragment fragment;
private static MainActivity activity;
private static SimpleCursorAdapter adapter;
public static MessagesFragment getInstance() {
if (fragment == null)
fragment = new MessagesFragment();
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activity = (MainActivity) getActivity();
adapter = new SimpleCursorAdapter(activity, R.layout.list_item, null,
new String[] {DataProvider.KEY_NUMBER, DataProvider.KEY_MESSAGE, DataProvider.KEY_TIME},
new int [] {R.id.item_field_number, R.id.item_field_message, R.id.item_field_time}, 0);
setListAdapter(adapter);
getLoaderManager().initLoader(0, null, this);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_messages, null);
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
activity.showDetails(Long.valueOf(id).intValue());
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(activity, DataProvider.CONTENT_URI, null, null, null, null);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
adapter.swapCursor(data);
while (data.moveToNext()) {
int id = data.getInt(data.getColumnIndex(DataProvider.KEY_ID));
int sent = data.getInt(data.getColumnIndex(DataProvider.KEY_SENT));
this.getListView().getChildAt(id).getBackground().setLevel(sent);
}
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
adapter.swapCursor(null);
}
公共类MessagesFragment扩展ListFragment实现
LoaderManager.LoaderCallbacks{
私有静态消息片段;
私人活动;
专用静态SimpleCursorAdapter适配器;
公共静态消息片段getInstance(){
if(片段==null)
fragment=newmessagesFragment();
返回片段;
}
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
活动=(MainActivity)getActivity();
adapter=new SimpleCursorAdapter(活动,R.layout.list_项,空,
新字符串[]{DataProvider.KEY_NUMBER,DataProvider.KEY_MESSAGE,DataProvider.KEY_TIME},
新int[]{R.id.item_字段_编号,R.id.item_字段_消息,R.id.item_字段_时间},0);
setListAdapter(适配器);
getLoaderManager().initLoader(0,null,this);
}
@凌驾
CreateView上的公共视图(布局、充气机、视图组容器、捆绑包保存状态){
返回充气器。充气(R.layout.fragment_消息,空);
}
@凌驾
public void onListItemClick(列表视图l、视图v、整数位置、长id){
super.onListItemClick(左、右、位置、id);
activity.showDetails(Long.valueOf(id).intValue());
}
@凌驾
公共加载器onCreateLoader(int-id,Bundle-args){
返回新的游标装入器(活动,DataProvider.CONTENT\u URI,null,null,null);
}
@凌驾
public void onLoadFinished(加载器、光标数据){
适配器。swapCursor(数据);
while(data.moveToNext()){
int id=data.getInt(data.getColumnIndex(DataProvider.KEY_id));
int sent=data.getInt(data.getColumnIndex(DataProvider.KEY_sent));
此.getListView().getChildAt(id).getBackground().setLevel(已发送);
}
}
@凌驾
公共void onLoaderReset(加载器){
适配器.swapCursor(空);
}
}这应该会有帮助
public class SampleAdapter extends SimpleCursorAdapter {
private LayoutInflater inflater;
private Cursor cursor;
private Context context;
public SampleAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) {
super(context, layout, c, from, to, flags);
this.context = context;
cursor = c;
inflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return cursor == null ? 0 : cursor.getCount();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (cursor != null) {
ViewHolder holder;
cursor.moveToPosition(position);
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_item, parent, false);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
convertView.getBackground().setLevel(cursor.getInt(cursor.getColumnIndex(DataProvider.KEY_SENT)));
holder.number.setText(cursor.getString(cursor.getColumnIndex(DataProvider.KEY_NUMBER)));
holder.message.setText(cursor.getColumnIndex(DataProvider.KEY_MESSAGE)));
holder.time.setText(cursor.getColumnIndex(DataProvider.KEY_TIME)));
}
return convertView;
}
@Override
public Cursor swapCursor(Cursor c) {
cursor = c;
return super.swapCursor(c);
}
private class ViewHolder {
TextView number;
TextView message;
TextView time;
public ViewHolder(View view) {
number = (TextView) view.findViewById(R.id.item_field_number);
message = (TextView) view.findViewById(R.id.item_field_message);
time = (TextView) view.findViewById(R.id.item_countries_time);
}
}
}
事实证明,我应该实现SimpleCursorAdapter,而不是使用回调方法。我要感谢@bbaker:)如果有人感兴趣,下面是代码:
private class CustomAdapter extends SimpleCursorAdapter {
private LayoutInflater inflater;
private int layout;
public CustomAdapter(Context context, int layout, Cursor cursor,
String[] from, int[] to, int flags) {
super(context, layout, cursor, from, to, flags);
inflater = LayoutInflater.from(context);
this.layout = layout;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return inflater.inflate(layout, null);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
super.bindView(view, context, cursor);
if (cursor != null && cursor.getCount() > 0) {
TextView timeView = (TextView) view.findViewById(R.id.item_field_time);
int sent = cursor.getInt(cursor.getColumnIndex(DataProvider.KEY_SENT));
timeView.getBackground().setLevel(sent);
}
}
}
非常感谢。现在我的帖子看起来好多了。希望我能更新您的编辑:)NullPointerException发生在哪里?LogCat指向这一行:
this.getListView().getChildAt(id.getBackground().setLevel(sent)代码>值不是空的。我已经检查过了。哪些值不是空的?我会将该行分成单独的行进行调试,打印每个函数的返回值。如果id
和sent
不为null,则其中一个函数在执行while循环期间返回null。我的钱在getChildAt(id)
上。好的,谢谢。我现在就试试这个。当我调用此方法时,可能没有实例化子视图。再次感谢!我听说取景器效率更高。也许我应该用它。只要我有足够的代表,我就会给你的帖子投票;)