我在片段A中有一个包含DialogFragment
的上下文菜单。在DialogFragment
的帮助下,我创建了一个保存在MediaStore.Playlists
中的播放列表。在片段B中,我显示带有播放列表的ListView
。
如何在添加新播放列表时更新片段B中的Listview
?
我的适配器上的P {I m trying to use
notifydatasetchanged()`,但它不起作用。
这是我无法更新的PlaylistFragment:
private ListView lvPlaylists;
private int[] images = new int[] { R.drawable.icon_playlist };
private ArrayList<HashMap<String, String>> listPlaylists = new ArrayList<HashMap<String, String>>();;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.playlists, null);
listPlaylists = getAllPlaylists(getActivity());
lvPlaylists = (ListView) v.findViewById(R.id.lvPlaylists);
List<Map<String, String>> data = new ArrayList<Map<String, String>>();
for (int i = 0; i < listPlaylists.size(); i++) {
Map<String, String> datum = new HashMap<String, String>(2);
datum.put("elementPlaylist",
listPlaylists.get(i).get("playlistName"));
datum.put("imagesPlaylist", Integer.toString(images[0]));
data.add(datum);
}
SimpleAdapter sAdapter = new SimpleAdapter(getActivity(), data,
R.layout.list_playlist_element, new String[] {
"elementPlaylist", "imagesPlaylist" }, new int[] {
R.id.tvName, R.id.ivIcon });
lvPlaylists.setAdapter(sAdapter);
lvPlaylists.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
String playlistId = listPlaylists.get(pos).get("playlistId");
Intent playlistSongs = new Intent(getActivity(),
PlaylistSongs.class);
playlistSongs.putExtra("playlistId", playlistId);
startActivity(playlistSongs);
}
});
return v;
}
public ArrayList<HashMap<String, String>> getAllPlaylists(Context context) {
String[] projection = { MediaStore.Audio.Playlists._ID, // 0
MediaStore.Audio.Playlists.NAME // 1
};
Cursor playListSDCardCursor = myquery(context,
MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, projection,
null, null, MediaStore.Audio.Playlists.NAME, 0);
if (playListSDCardCursor.moveToFirst()) {
for (int i = 0; i < playListSDCardCursor.getCount(); i++) {
HashMap<String, String> playlist = new HashMap<String, String>();
playlist.put(
"playlistName",
playListSDCardCursor.getString(playListSDCardCursor
.getColumnIndex(MediaStore.Audio.Playlists.NAME)));
playlist.put(
"playlistId",
playListSDCardCursor.getString(playListSDCardCursor
.getColumnIndex(MediaStore.Audio.Playlists._ID)));
listPlaylists.add(playlist);
playListSDCardCursor.moveToNext();
}
}
playListSDCardCursor.close();
return listPlaylists;
}
public static Cursor myquery(Context context, Uri uri, String[] projection,
String selection, String[] selectionArgs, String sortOrder,
int limit) {
try {
ContentResolver resolver = context.getContentResolver();
if (resolver == null) {
return null;
}
if (limit > 0) {
uri = uri.buildUpon().appendQueryParameter("limit", "" + limit)
.build();
}
return resolver.query(uri, projection, selection, selectionArgs,
sortOrder);
} catch (UnsupportedOperationException ex) {
return null;
}
}
这是我创建新播放列表的DialogFragment:
public class MyDialogFragment extends DialogFragment {
Context mContext;
public MyDialogFragment() {
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("Введите имя плейлиста:");
final EditText input = new EditText(getActivity());
input.setId(0);
builder.setView(input);
builder.setPositiveButton("Ок", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
String value = input.getText().toString();
Log.d("", "User name: " + value);
if (value != null) {
ContentValues cv = new ContentValues();
cv.put(MediaStore.Audio.Playlists.NAME, value);
Uri uri = getActivity().getContentResolver().insert(
MediaStore.Audio.Playlists
.getContentUri("external"), cv);
}
return;
}
});
builder.setNegativeButton("Отмена",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
return builder.create();
}
}
这是TrackFragment,我调用上下文菜单并显示FragmentDialog:
public class TrackFragment extends Fragment {
private ListView lvTracks;
private static ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();
private int songIndex;
private Utilities utils;
private ArrayList<HashMap<String, String>> listPlaylists = new ArrayList<HashMap<String, String>>();;
private int countPlaylist = 0;
private int itemPosition;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.track, null);
utils = new Utilities();
songsList = getAllSongs(getActivity());
List<Map<String, String>> data = new ArrayList<Map<String, String>>();
for (int i = 0; i < songsList.size(); i++) {
Map<String, String> datum = new HashMap<String, String>(2);
datum.put("songTitle", songsList.get(i).get("songTitle"));
datum.put("songArtist", songsList.get(i).get("songArtist"));
datum.put("songDuration", songsList.get(i).get("songDuration"));
datum.put("songAlbum", songsList.get(i).get("songAlbum"));
data.add(datum);
}
lvTracks = (ListView) v.findViewById(R.id.lvTracks);
lvTracks.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
songIndex = position;
writeData();
Intent mainIntent = new Intent(getActivity().getBaseContext(),
PlayerActivity.class);
mainIntent.putExtra("songIndex", position);
Bundle b = new Bundle();
b.putInt("songIndex", position);
b.putInt("mediaIndex",
Integer.parseInt(songsList.get(position).get("songId")));
mainIntent.putExtras(b);
int albumId = Integer.parseInt(songsList.get(position).get(
"songAlbum"));
Bitmap cover = utils.getAlbumart(albumId, getActivity()
.getApplicationContext());
if (cover == null) {
cover = BitmapFactory.decodeResource(getResources(),
R.drawable.nocover);
}
ByteArrayOutputStream stream = new ByteArrayOutputStream();
cover.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
mainIntent.putExtra("albumArt", byteArray);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(mainIntent);
}
});
registerForContextMenu(lvTracks);
SimpleAdapter sAdapter = new SimpleAdapter(getActivity(), data,
R.layout.list_track_element, new String[] { "songTitle",
"songArtist", "songDuration" },
new int[] { R.id.tvSongName, R.id.tvSongArtist,
R.id.tvSongDuration });
lvTracks.setAdapter(sAdapter);
return v;
}
public void onCreateContextMenu(android.view.ContextMenu menu, View v,
android.view.ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
countPlaylist++;
if (countPlaylist > 1) {
listPlaylists.clear();
listPlaylists = getAllPlaylists(getActivity()
.getApplicationContext());
} else {
listPlaylists = getAllPlaylists(getActivity()
.getApplicationContext());
}
menu.setHeaderIcon(R.drawable.ic_launcher);
menu.setHeaderTitle("Добавить в плейлист");
menu.add(0, 0, 0, "Новый плейлист");
for (int i = 0; i < listPlaylists.size(); i++)
menu.add(0, i + 1, 0, listPlaylists.get(i).get("playlistName"));
}
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
.getMenuInfo();
itemPosition = info.position;
if (item.getItemId() == 0) {
createPlaylist(item.getItemId());
}
else {
Log.d("Playlist id",
Integer.parseInt(listPlaylists.get(item.getItemId()).get(
"playlistId"))
+ "");
addToPlaylist(Integer.valueOf(listPlaylists.get(
item.getItemId() - 1).get("playlistId")));
}
return true;
}
private void createPlaylist(int itemId) {
new MyDialogFragment().show(getFragmentManager(), "MyDialog");
}
private void addToPlaylist(int playlistId) {
ContentResolver resolver = getActivity().getContentResolver();
String[] cols = new String[] { "count(*)" };
Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external",
playlistId);
Cursor cur = resolver.query(uri, cols, null, null, null);
cur.moveToFirst();
final int base = cur.getInt(0);
cur.close();
ContentValues values = new ContentValues();
values.put(MediaStore.Audio.Playlists.Members.PLAY_ORDER,
Integer.valueOf(base + 1));
values.put(MediaStore.Audio.Playlists.Members.AUDIO_ID,
Integer.valueOf(songsList.get(itemPosition).get("songId")));
Log.d("mediaIndex", songsList.get(itemPosition).get("songId") + "");
resolver.insert(uri, values);
}
public ArrayList<HashMap<String, String>> getAllPlaylists(Context context) {
String[] projection = { MediaStore.Audio.Playlists._ID,
MediaStore.Audio.Playlists.NAME };
Cursor playListSDCardCursor = myquery(context,
MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, projection,
null, null, MediaStore.Audio.Playlists.NAME, 0);
if (playListSDCardCursor.moveToFirst()) {
for (int i = 0; i < playListSDCardCursor.getCount(); i++) {
HashMap<String, String> playlist = new HashMap<String, String>();
playlist.put(
"playlistName",
playListSDCardCursor.getString(playListSDCardCursor
.getColumnIndex(MediaStore.Audio.Playlists.NAME)));
playlist.put(
"playlistId",
playListSDCardCursor.getString(playListSDCardCursor
.getColumnIndex(MediaStore.Audio.Playlists._ID)));
listPlaylists.add(playlist);
playListSDCardCursor.moveToNext();
}
}
playListSDCardCursor.close();
return listPlaylists;
}
}
我已部分解决了手动添加播放列表的问题:
Map<String, String> datum = new HashMap<String, String>(2);
datum.put("elementPlaylist", value);
datum.put("imagesPlaylist", Integer.toString(images[0]));
PlaylistFragment.data.add(datum);
列表视图中添加了播放列表,但点击后抛出:
java.lang.IndexOutOfBoundsException: Invalid index 18, size is 18
答案 0 :(得分:0)
使用CursorLoader填充列表片段 http://developer.android.com/reference/android/content/CursorLoader.html
它会将通知uri设置为您的Cursor sp它将自动更新
让你的片段实现LoaderCallbacks
class PlaylistFragment extends Fragment implements LoaderCallbacks<Cursor>{
@Override
public void onLoaderReset(Loader<Cursor> arg0) {
sAdapter.swapCursor(null);
}
@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
return new CursorLoader(getActivity(), MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI, projection, null, null, null)
}
@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor result) {
sAdapter.swapCursor(result);
}
@Override
public void onStart(){
getLoaderManager().restartLoader(0, null, this);
}
}
多数情况下,加载程序会自动重新显示播放列表更改