Android 我们使用的游标的新适配器 *从媒体商店内容提供商处接收。然后将适配器设置为 *列表显示了。适配器使用ARIST、相册和标题显示到 *用户。 */ 公共void onLoadFinished(加载器游标加载器,游标游标) { if(适配器==null) { 适配器=新媒体选择器或适配器(getApplicationContext(),R.layout.activity\u媒体选择器,光标,新字符串[]{ MediaStore.Audio.Media.ARTIST,MediaStore.Audio.Media.ALBUM,MediaStore.Audio.Media.TITLE},新int[]{R.id.text_1, R.id.text_2,R.id.text_3},Adapter.NO_SELECTION,selectedItems); setAdapter(适配器); } 其他的 { 适配器.swapCursor(游标); } } /** *当重新设置加载程序时,我们只需将null作为光标传递给 *适配器。 */ public void onLoaderReset(加载器游标加载器) { 适配器.swapCursor(空); } }
这是我的适配器代码:Android 我们使用的游标的新适配器 *从媒体商店内容提供商处接收。然后将适配器设置为 *列表显示了。适配器使用ARIST、相册和标题显示到 *用户。 */ 公共void onLoadFinished(加载器游标加载器,游标游标) { if(适配器==null) { 适配器=新媒体选择器或适配器(getApplicationContext(),R.layout.activity\u媒体选择器,光标,新字符串[]{ MediaStore.Audio.Media.ARTIST,MediaStore.Audio.Media.ALBUM,MediaStore.Audio.Media.TITLE},新int[]{R.id.text_1, R.id.text_2,R.id.text_3},Adapter.NO_SELECTION,selectedItems); setAdapter(适配器); } 其他的 { 适配器.swapCursor(游标); } } /** *当重新设置加载程序时,我们只需将null作为光标传递给 *适配器。 */ public void onLoaderReset(加载器游标加载器) { 适配器.swapCursor(空); } },android,android-listview,android-cursoradapter,Android,Android Listview,Android Cursoradapter,这是我的适配器代码: /** * This adapter is used by the media selector activity to display the list rows. * It is needed to keep track of which checkboxes have been checked and which * has not. The system is aggressive in trying to re-use views that are not
/**
* This adapter is used by the media selector activity to display the list rows.
* It is needed to keep track of which checkboxes have been checked and which
* has not. The system is aggressive in trying to re-use views that are not
* currently being displayed which leads to strange behaviour with the
* checkboxes where they keep their "checked" state although they have not been
* checked for a specific item.
*
* The class is extending SimpleCursorAdapter for easy use of the cursor that
* can be obtained from a database or content resolver.
*
* @author Daniel Kvist
*
*/
public class MediaSelectorAdapter extends SimpleCursorAdapter
{
private Context context;
private ArrayList<Track> listItems;
private ArrayList<Track> selectedItems;
/**
* The constructor takes the same parameters as an ordinary simple cursor
* adapter and passes them up to the super class. It then loops through the
* cursor and initiates an array which contains references to all the list
* rows and if they have been checked or not.
*
* @param context
* the context which to be displayed in
* @param layout
* the layout file for the list view
* @param cursor
* the cursor that points to the data
* @param from
* the fields that are to be displayed
* @param to
* the views to display the fields in
* @param flags
* any special flags that can be used to determine the behaviour
* of the super class adapter
* @param selectedItems2
*/
public MediaSelectorAdapter(Context context, int layout, Cursor cursor, String[] from, int[] to, int flags, ArrayList<Track> selectedItems)
{
super(context, layout, cursor, from, to, flags);
this.context = context;
this.selectedItems = selectedItems;
listItems = new ArrayList<Track>();
while (cursor.moveToNext())
{
Track track = new Track(cursor.getString(0), cursor.getString(1), cursor.getString(2), cursor.getString(3),
cursor.getString(4), cursor.getString(5), cursor.getString(6));
listItems.add(track);
}
}
/**
* Overridden method that getView uses to keep track of how many items the
* adapter has.
*/
@Override
public int getCount()
{
return listItems.size();
}
/**
* Called by the system to get a specific item.
*/
@Override
public Track getItem(int position)
{
return listItems.get(position);
}
/**
* Called by the system to get the id/position for an item.
*/
@Override
public long getItemId(int position)
{
return position;
}
/**
* Reuses old views if they have not already been reset and inflates new
* views for the rows in the list that needs a new one. It the adds a
* listener to each checkbox that is used to store information about which
* checkboxes have been checked or not. Finally we set the checked status of
* the checkbox and let the super class do it's thing.
*/
@Override
public View getView(final int position, View convertView, ViewGroup parent)
{
if (convertView == null)
{
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.media_selector_item_layout, null);
}
final CheckBox checkBox = (CheckBox) convertView.findViewById(R.id.checkbox);
checkBox.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
CheckBox cb = (CheckBox) v.findViewById(R.id.checkbox);
if (cb.isChecked())
{
selectedItems.add(listItems.get(position));
}
else if (!cb.isChecked())
{
selectedItems.remove(listItems.get(position));
}
}
});
// If the selected items contains the current item, set the checkbox to be checked
checkBox.setChecked(selectedItems.contains(listItems.get(position)));
return super.getView(position, convertView, parent);
}
/**
* Returns an array list with all the selected items as Track objects.
*
* @return the selected items
*/
public ArrayList<Track> getSelectedItems()
{
return selectedItems;
}
}
/**
*媒体选择器活动使用此适配器显示列表行。
*需要跟踪哪些复选框已被选中,哪些已被选中
*没有。该系统在尝试重用不可用的视图时非常积极
*当前正在显示,这会导致
*复选框,它们保持其“选中”状态,尽管尚未选中
*检查特定项目。
*
*该类正在扩展SimpleCursorAdapter,以便于使用
*可以从数据库或内容解析器中获取。
*
*@作者丹尼尔·克维斯特
*
*/
公共类MediaSelectorAdapter扩展了SimpleCorsAdapter
{
私人语境;
私有ArrayList列表项;
私有数组列表selectedItems;
/**
*构造函数采用与普通简单游标相同的参数
*适配器并将它们传递给超类。然后它通过
*游标并启动一个数组,该数组包含对所有列表的引用
*行以及是否已检查它们。
*
*@param上下文
*要在其中显示的上下文
*@param布局
*列表视图的布局文件
*@param游标
*指向数据的光标
*@param from
*要显示的字段
*@param to
*要在其中显示字段的视图
*@param标志
*可用于确定行为的任何特殊标志
*超级类适配器的定义
*@param selectedItems2
*/
公共媒体选择器适配器(上下文上下文、int布局、光标、字符串[]from、int[]to、int标志、ArrayList selectedItems)
{
超级(上下文、布局、光标、从、到、标志);
this.context=上下文;
this.selectedItems=selectedItems;
listItems=new ArrayList();
while(cursor.moveToNext())
{
Track Track=新轨迹(cursor.getString(0)、cursor.getString(1)、cursor.getString(2)、cursor.getString(3),
cursor.getString(4)、cursor.getString(5)、cursor.getString(6));
添加(跟踪);
}
}
/**
*getView用于跟踪存储的项目数的重写方法
*适配器已安装。
*/
@凌驾
public int getCount()
{
返回listItems.size();
}
/**
*由系统调用以获取特定项。
*/
@凌驾
公共轨道getItem(内部位置)
{
返回listItems.get(位置);
}
/**
*由系统调用以获取项目的id/位置。
*/
@凌驾
公共长getItemId(int位置)
{
返回位置;
}
/**
*如果旧视图尚未重置,则重用旧视图并对新视图进行充气
*列表中需要新行的行的视图
*侦听器指向用于存储有关以下内容的信息的每个复选框:
*复选框是否已选中。最后,我们设置
*选中复选框并让超级类执行它的操作。
*/
@凌驾
公共视图getView(最终整数位置、视图转换视图、视图组父视图)
{
if(convertView==null)
{
LayoutFlater充气器=(LayoutFlater)context.getSystemService(context.LAYOUT\u充气器\u服务);
convertView=充气机。充气(R.layout.media\u selector\u item\u layout,null);
}
final CheckBox=(CheckBox)convertView.findViewById(R.id.CheckBox);
checkBox.setOnClickListener(新的OnClickListener()
{
公共void onClick(视图v)
{
复选框cb=(复选框)v.findViewById(R.id.CheckBox);
if(cb.isChecked())
{
选择editems.add(listItems.get(position));
}
如果(!cb.isChecked())
{
选择editems.remove(listItems.get(position));
}
}
});
//如果所选项目包含当前项目,请将复选框设置为选中
checkBox.setChecked(selectedItems.contains(listItems.get(position));
返回super.getView(position、convertView、parent);
}
/**
*返回一个数组列表,其中所有选定项都作为轨迹对象。
*
*@返回所选项目
*/
公共阵列列表getSelectedItems()
{
返回selectedItems;
}
}
任何提示、提示或其他输入都将不胜感激
谢谢好的,这就是我的结局。您可以随意使用它。解决方案根本不使用列表,而是将游标与getCursor()一起使用,这就是我们首先使用游标适配器的原因 活动:
/**
* This activity displays a list of the available media on the device. It allows
* selecting several items from the list and by selecting the "done" icon in the
* options menu, the activity will return the results to the calling activity.
*
* The list can be sorted via the options menu. The available sorting columns
* are artist, title and album. By default the list is sorted by artist name.
*
* The selection from the database consists of the _ID, ARTIST, ALBUM, TITLE,
* DATA, DISPLAY_NAME and DURATION columns and is also limited to contain only
* files that are markes as IS_MUSIC.
*
* @author Daniel Kvist
*
*/
public class MediaSelectorActivity extends Activity implements LoaderCallbacks<Cursor>
{
private static final int LOADER_ID_ARTIST = 2;
private static final int LOADER_ID_ALBUM = 4;
private static final int LOADER_ID_TITLE = 8;
public static final String EXTRA_SELECTED_ITEMS = "selected_media";
public static final int REQUEST_MEDIA = 0;
private MediaSelectorAdapter adapter;
private ListView listView;
private LoaderManager loaderManager;
private String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
private String[] projection = { MediaStore.Audio.Media._ID, MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.DISPLAY_NAME, MediaStore.Audio.Media.DURATION };
private ArrayList<Track> selectedItems;
/**
* The onCreate method loads the xml layout which contains the listview. It
* also gets the loader manager and initiates a first load of available
* media and sorts it by artist name.
*/
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_media_selector);
loaderManager = getLoaderManager();
loaderManager.initLoader(LOADER_ID_ARTIST, null, this);
listView = (ListView) findViewById(R.id.list);
selectedItems = new ArrayList<Track>();
}
/**
* This method simply inflates the xml file which contains the menu options.
*/
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.media_selector_menu, menu);
return true;
}
/**
* This is called when an option item has been selected. Depending on the
* user selection either the selected tracks are passed back to the calling
* activity or a new query is made to the media store to sort on either
* artist, album or title.
*/
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
selectedItems = adapter.getSelectedItems();
switch (item.getItemId())
{
case R.id.done:
Intent intent = new Intent();
intent.putParcelableArrayListExtra(EXTRA_SELECTED_ITEMS, selectedItems);
setResult(RESULT_OK, intent);
finish();
return true;
case R.id.artist:
loaderManager.initLoader(LOADER_ID_ARTIST, null, this);
return true;
case R.id.album:
loaderManager.initLoader(LOADER_ID_ALBUM, null, this);
return true;
case R.id.track:
loaderManager.initLoader(LOADER_ID_TITLE, null, this);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/**
* Called when the cursor loader is first created. It decides which URI to
* query and which sorting order should be returned. The query also contains
* information about which columns we are interested in which selection we
* want.
*/
public Loader<Cursor> onCreateLoader(int i, Bundle bundle)
{
CursorLoader cursorLoader = null;
switch (i)
{
case LOADER_ID_ARTIST:
cursorLoader = new CursorLoader(this, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, projection, selection, null,
MediaStore.Audio.Media.ARTIST);
break;
case LOADER_ID_ALBUM:
cursorLoader = new CursorLoader(this, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, projection, selection, null,
MediaStore.Audio.Media.ALBUM);
break;
case LOADER_ID_TITLE:
cursorLoader = new CursorLoader(this, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, projection, selection, null,
MediaStore.Audio.Media.TITLE);
break;
}
return cursorLoader;
}
/**
* When the load has finished we create a new adapter of the cursor we
* receive from the media store content provider. The adapter is then set to
* the listvew. The adapter uses ARIST, ALBUM and TITLE to be displayed to the
* user.
*/
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor)
{
if(adapter == null)
{
adapter = new MediaSelectorAdapter(getApplicationContext(), R.layout.activity_media_selector, cursor, new String[] {
MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.ALBUM, MediaStore.Audio.Media.TITLE }, new int[] { R.id.text_1,
R.id.text_2, R.id.text_3 }, Adapter.NO_SELECTION, selectedItems);
listView.setAdapter(adapter);
}
else
{
adapter.swapCursor(cursor);
}
}
/**
* WHen the loader is reset we just pass in null as the cursor to the
* adapter.
*/
public void onLoaderReset(Loader<Cursor> cursorLoader)
{
adapter.swapCursor(null);
}
}
/**
*此活动显示硬盘上可用介质的列表
/**
* This activity displays a list of the available media on the device. It allows
* selecting several items from the list and by selecting the "done" icon in the
* options menu, the activity will return the results to the calling activity.
*
* The list can be sorted via the options menu. The available sorting columns
* are artist, title and album. By default the list is sorted by artist name.
*
* The selection from the database consists of the _ID, ARTIST, ALBUM, TITLE,
* DATA, DISPLAY_NAME and DURATION columns and is also limited to contain only
* files that are markes as IS_MUSIC.
*
* @author Daniel Kvist
*
*/
public class MediaSelectorActivity extends Activity implements LoaderCallbacks<Cursor>
{
private static final int LOADER_ID_ARTIST = 2;
private static final int LOADER_ID_ALBUM = 4;
private static final int LOADER_ID_TITLE = 8;
public static final String EXTRA_SELECTED_ITEMS = "selected_media";
public static final int REQUEST_MEDIA = 0;
private MediaSelectorAdapter adapter;
private ListView listView;
private LoaderManager loaderManager;
private String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
private String[] projection = { MediaStore.Audio.Media._ID, MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.DISPLAY_NAME, MediaStore.Audio.Media.DURATION };
private ArrayList<Track> selectedItems;
/**
* The onCreate method loads the xml layout which contains the listview. It
* also gets the loader manager and initiates a first load of available
* media and sorts it by artist name.
*/
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_media_selector);
loaderManager = getLoaderManager();
loaderManager.initLoader(LOADER_ID_ARTIST, null, this);
listView = (ListView) findViewById(R.id.list);
selectedItems = new ArrayList<Track>();
}
/**
* This method simply inflates the xml file which contains the menu options.
*/
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.media_selector_menu, menu);
return true;
}
/**
* This is called when an option item has been selected. Depending on the
* user selection either the selected tracks are passed back to the calling
* activity or a new query is made to the media store to sort on either
* artist, album or title.
*/
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
selectedItems = adapter.getSelectedItems();
switch (item.getItemId())
{
case R.id.done:
Intent intent = new Intent();
intent.putParcelableArrayListExtra(EXTRA_SELECTED_ITEMS, selectedItems);
setResult(RESULT_OK, intent);
finish();
return true;
case R.id.artist:
loaderManager.initLoader(LOADER_ID_ARTIST, null, this);
return true;
case R.id.album:
loaderManager.initLoader(LOADER_ID_ALBUM, null, this);
return true;
case R.id.track:
loaderManager.initLoader(LOADER_ID_TITLE, null, this);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/**
* Called when the cursor loader is first created. It decides which URI to
* query and which sorting order should be returned. The query also contains
* information about which columns we are interested in which selection we
* want.
*/
public Loader<Cursor> onCreateLoader(int i, Bundle bundle)
{
CursorLoader cursorLoader = null;
switch (i)
{
case LOADER_ID_ARTIST:
cursorLoader = new CursorLoader(this, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, projection, selection, null,
MediaStore.Audio.Media.ARTIST);
break;
case LOADER_ID_ALBUM:
cursorLoader = new CursorLoader(this, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, projection, selection, null,
MediaStore.Audio.Media.ALBUM);
break;
case LOADER_ID_TITLE:
cursorLoader = new CursorLoader(this, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, projection, selection, null,
MediaStore.Audio.Media.TITLE);
break;
}
return cursorLoader;
}
/**
* When the load has finished we create a new adapter of the cursor we
* receive from the media store content provider. The adapter is then set to
* the listvew. The adapter uses ARIST, ALBUM and TITLE to be displayed to the
* user.
*/
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor)
{
if(adapter == null)
{
adapter = new MediaSelectorAdapter(getApplicationContext(), R.layout.activity_media_selector, cursor, new String[] {
MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.ALBUM, MediaStore.Audio.Media.TITLE }, new int[] { R.id.text_1,
R.id.text_2, R.id.text_3 }, Adapter.NO_SELECTION, selectedItems);
listView.setAdapter(adapter);
}
else
{
adapter.swapCursor(cursor);
}
}
/**
* WHen the loader is reset we just pass in null as the cursor to the
* adapter.
*/
public void onLoaderReset(Loader<Cursor> cursorLoader)
{
adapter.swapCursor(null);
}
}
/**
* This adapter is used by the media selector activity to display the list rows.
* It is needed to keep track of which checkboxes have been checked and which
* has not. The system is aggressive in trying to re-use views that are not
* currently being displayed which leads to strange behaviour with the
* checkboxes where they keep their "checked" state although they have not been
* checked for a specific item.
*
* The class is extending SimpleCursorAdapter for easy use of the cursor that
* can be obtained from a database or content resolver.
*
* @author Daniel Kvist
*
*/
public class MediaSelectorAdapter extends SimpleCursorAdapter
{
private Context context;
private ArrayList<Track> selectedItems;
/**
* The constructor takes the same parameters as an ordinary simple cursor
* adapter and passes them up to the super class. It then loops through the
* cursor and initiates an array which contains references to all the list
* rows and if they have been checked or not.
*
* @param context
* the context which to be displayed in
* @param layout
* the layout file for the list view
* @param cursor
* the cursor that points to the data
* @param from
* the fields that are to be displayed
* @param to
* the views to display the fields in
* @param flags
* any special flags that can be used to determine the behaviour
* of the super class adapter
* @param selectedItems2
*/
public MediaSelectorAdapter(Context context, int layout, Cursor cursor, String[] from, int[] to, int flags, ArrayList<Track> selectedItems)
{
super(context, layout, cursor, from, to, flags);
this.context = context;
this.selectedItems = selectedItems;
}
/**
* Reuses old views if they have not already been reset and inflates new
* views for the rows in the list that needs a new one. It the adds a
* listener to each checkbox that is used to store information about which
* checkboxes have been checked or not. Finally we set the checked status of
* the checkbox and let the super class do it's thing.
*/
@Override
public View getView(final int position, View convertView, ViewGroup parent)
{
Cursor c = getCursor();
c.moveToPosition(position);
final Track track = new Track(c.getString(0), c.getString(1), c.getString(2), c.getString(3),
c.getString(4), c.getString(5), c.getString(6));
if (convertView == null)
{
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.media_selector_item_layout, null);
}
final CheckBox checkBox = (CheckBox) convertView.findViewById(R.id.checkbox);
checkBox.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
CheckBox cb = (CheckBox) v.findViewById(R.id.checkbox);
if (cb.isChecked())
{
selectedItems.add(track);
}
else if (!cb.isChecked())
{
selectedItems.remove(track);
}
}
});
// If the selected items contains the current item, set the checkbox to be checked
checkBox.setChecked(selectedItems.contains(track));
return super.getView(position, convertView, parent);
}
/**
* Returns an array list with all the selected items as Track objects.
*
* @return the selected items
*/
public ArrayList<Track> getSelectedItems()
{
return selectedItems;
}
}