2015-01-09 231 views
1

我有一个自定义的CursorAdapter和2种布局类型的列表视图。在onCreate中,我只用一种布局类型填充本地数据库中的数据。然后,我从互联网上下载一些数据,并向列表视图的顶部添加一行(使用以下方法:How to insert extra elements into a SimpleCursorAdapter or Cursor for a Spinner?),使用不同的布局。我假设适配器重用了旧的布局,因为新的布局没有膨胀,并且在bindView中填充行时,应用程序崩溃时出现NullPointerException(我没有为第二种布局类型使用视图,因为它只有一行)。我怎么解决这个问题?我可以强迫适配器以某种方式“观察”视图吗?动态添加不同布局的项目到列表视图

下面是我的代码大致是这样的:

片段:

public class MyFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor>{ 

    private ListView mListView; 
    private CustomCursorAdapter cursorAdapter; 

    public MyFragment() { 
    } 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     getLoaderManager().initLoader(0, null, this); 
     super.onActivityCreated(savedInstanceState); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     mListView = (ListView)inflater.inflate(R.layout.fragment, container, false); 

     cursorAdapter = new CustomCursorAdapter(getActivity(), null, 0); 
     mListView.setAdapter(cursorAdapter); 

     return mListView; 
    } 

    @Override 
    public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
     return new CursorLoader(
       getActivity(), 
       CONTENT_URI, 
       projection, 
       selection, 
       selectionArgs, 
       sortOrder 
     ); 
    } 

    @Override 
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
     cursorAdapter.swapCursor(data); 
     new SomeTask().execute(/*params*/); 
    } 

    @Override 
    public void onLoaderReset(Loader<Cursor> loader) { 
     cursorAdapter.swapCursor(null); 
    } 

    private class SomeTask extends AsyncTask<String, Void, String>{ 

     @Override 
     protected String doInBackground(String... params) { 
      //Download some stuff 
     } 

     @Override 
     protected void onPostExecute(String s) { 
      //Add downloaded stuff to cursor 
      cursorAdapter.swapCursor(extendedCursor); 
     } 
    } 
} 

适配器:

public class CustomCursorAdapter extends CursorAdapter { 

    private static final int VIEW_TYPE_COUNT = 2; 
    private static final int VIEW_TYPE_ONE = 0; 
    private static final int VIEW_TYPE_TWO = 1; 

    public CustomCursorAdapter(Context context, Cursor c, int flags) { 
     super(context, c, flags); 
    } 

    @Override 
    public View newView(Context context, Cursor cursor, ViewGroup parent) { 
     int viewType = getItemViewType(cursor.getPosition()); 
     View view; 
     switch (viewType) { 
      case VIEW_TYPE_ONE: { 
       view = LayoutInflater.from(context).inflate(R.layout.layout_one, parent, false); 

       ViewHolder viewHolder = new ViewHolder(view); 
       view.setTag(viewHolder); 
      } 
      case VIEW_TYPE_TWO: { 
       view = LayoutInflater.from(context).inflate(R.layout.layout_two, parent, false); 
      } 
     } 
     return view; 
    } 

    @Override 
    public void bindView(View view, Context context, Cursor cursor) { 
     int viewType = getItemViewType(cursor.getPosition()); 
     switch (viewType){ 
      case VIEW_TYPE_ONE: 
       // populate view using the viewholder 
       break; 
      case VIEW_TYPE_TWO: 
       // populate newly added row, ((TextView)findViewById).setText() throws NullPointerException 
       break; 
     } 
    } 

    @Override 
    public int getItemViewType(int position) { 
     return /*is the new view added*/ && position == 0 ? VIEW_TYPE_TWO : VIEW_TYPE_ONE; 
    } 

    @Override 
    public int getViewTypeCount() { 
     return VIEW_TYPE_COUNT; 
    } 

    public static class ViewHolder { 

     //cache views here 

     public ViewHolder(View view) { 
     } 
    } 
} 

回答

1

您忘记了switchbreak声明newView方法。

+0

我的确如此。有时我需要在背上拍一下,以提醒我我有多特别:)我经常忘记那些...... – Longi 2015-01-10 00:13:26

0

一种方式做到这一点是使用含有单一视图两个视图的所有元素以及每个元素都使用.setEnabled(boolean)和/或.setVisibility(int)来控制显示哪些元素。

+0

但这很丑:c – Longi 2015-01-09 23:49:31

+0

是的,代码会变得有点难看。你可以通过使用某种viewGroup来清理它。屏幕上的显示仍然应该看起来如何。 – pgs 2015-01-09 23:59:18

相关问题