gpt4 book ai didi

android - 为什么 notifyItemRemoved(getAdapterPosition());不管用

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:56:38 26 4
gpt4 key购买 nike

我正在使用 RecyclerView 显示 mp3 歌曲列表。现在问题出在我尝试删除歌曲时。这首歌已成功删除,但该项目仍保留在 RecyclerView 中,我认为它会重新创建自己,实际上我不明白它是什么。这是发生了什么的屏幕截图。 enter image description here

如您在上面的屏幕截图中所见。我尝试删除一首歌曲,但该歌曲仍保留在列表中,并且还在其后面创建了另一个列表。我不知道会发生什么。这是我的代码 SongFragment:-

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
activityView = inflater.inflate(R.layout.fragment_song, container, false);
// SongsLibrary songsLibrary = new SongsLibrary();
// songsLibrary.getSongThumnail(getActivity(), songArt);
swipeRefreshLayout = activityView.findViewById(R.id.swiperefresh);
if(arrayList == null){
SongsLibrary songsLibrary = new SongsLibrary();
songsLibrary.getSongs(getActivity());
}
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(deteleSong);
setUpMusic();
return activityView;
}

private void setUpMusic() {

// todo when there is no activity and no song player than arraylist.size on null object
RecyclerView songRecyclerView = activityView.findViewById(R.id.song_list);
songRecyclerView.setNestedScrollingEnabled(false);
songRecyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
songRecyclerView.setLayoutManager(linearLayoutManager);
songRecyclerView.setHasFixedSize(true);
SongAdapter mAdapter = new SongAdapter(getActivity(), getMusic());
songRecyclerView.setAdapter(mAdapter);
}

public List<SongObject> getMusic() {
List<SongObject> recentSongs = new ArrayList<>();
names = new String[arrayList.size()];
names = arrayList.toArray(names);

singer = new String[artistName.size()];
singer = artistName.toArray(singer);

art = new String[songThumb.size()];
art = songThumb.toArray(art);

for(int i = 0; i < arrayList.size(); i++){
recentSongs.add(new SongObject(names[i], singer[i], art[i]));
}
return recentSongs;
}

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}

BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
switch (action)
{
case deteleSong:
int postion = intent.getIntExtra("position",0); //todo remove item by position
break;
}
}
};

@Override
public void onDestroy() {
super.onDestroy();

}

@Override
public void onPause() {
super.onPause();
if(broadcastReceiver != null)
getActivity().unregisterReceiver(broadcastReceiver);
}

歌曲适配器.java

public class SongAdapter extends RecyclerView.Adapter<SongViewHolder>{
private Context context;
private List<SongObject> allSongs;
MyEditText options;
SongViewHolder songViewHolder;
public SongAdapter(Context context, List<SongObject> allSongs) {
this.context = context;
this.allSongs = allSongs;
}
@Override
public SongViewHolder onCreateViewHolder(ViewGroup parent, final int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.song_list_layout, parent, false);
options = view.findViewById(R.id.options);
return new SongViewHolder(view);
}
@Override
public void onBindViewHolder(SongViewHolder holder, final int position) {
songViewHolder = holder;
holder.setIsRecyclable(false);
options.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showOptions(view, position);
}
});
SongObject songs = allSongs.get(position);
holder.songTitle.setText(songs.getSongTitle());
holder.songAuthor.setText(songs.getSongAuthor());
Glide.with(context)
.load(songs.getSongCover())
.asBitmap()
.placeholder(R.drawable.player)
.error(R.drawable.player)
.override(200,200)
.fitCenter()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(holder.songImage);
}
private void showOptions(final View v, final int pos) {
PopupMenu popup = new PopupMenu(context, v);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.song_options, popup.getMenu());
popup.show();

popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
int id = menuItem.getItemId();
switch (id) {
case R.id.optionPlay:
play(context, pos);
// songFragment.play(context, pos);
break;
case R.id.optionDelete:
showAlert(context, pos);
break;
case R.id.optionDetails:
// getSongDetails(context, pos);
break;
}
return true;
}
});
}

public void play(Context context, int pos){
// Start Service when User Select a song :)
Intent serviceIntent = new Intent(context, NotificationService.class);
serviceIntent.setAction(Constants.ACTION.STARTFOREGROUND_ACTION);
serviceIntent.putExtra("pos", pos);
serviceIntent.putExtra("search","");
// Log.d("SendingData","Sended :"+ songIndex);
context.startService(serviceIntent);
//send broadcast for showing slideup panel
//send Broadcast
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(MusicActivity.mMediaStart);
broadcastIntent.putExtra("isStart", 1);
context.sendBroadcast(broadcastIntent);
}
private void showAlert(final Context context, final int position){
AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.Theme_AppCompat_Light_Dialog_Alert);
builder.setMessage("Do you want to delete this song?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
deleteSong(context, position);
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {

}
});
// Create the AlertDialog object and return it
builder.show();
}
public void deleteSong(Context ctx, int pos){
ArrayList<String> songList = songPath;
final String songName = songList.get(pos);
final int songPos = pos;
new android.os.Handler().postDelayed(new Runnable(){
@Override
public void run() {
// Set up the projection (we only need the ID)
String[] projection = { MediaStore.Audio.Media._ID };

// Match on the file path
String selection = MediaStore.Audio.Media.DATA + " = ?";
String[] selectionArgs = new String[] { songName };

// Query for the ID of the media matching the file path
Uri queryUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
ContentResolver contentResolver = context.getContentResolver();
Cursor c = contentResolver.query(queryUri, projection, selection, selectionArgs, null);
if (c.moveToFirst()) {
// We found the ID. Deleting the item via the content provider will also remove the file
long id = c.getLong(c.getColumnIndexOrThrow(MediaStore.Audio.Media._ID));
Uri deleteUri = ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id);
contentResolver.delete(deleteUri, null, null);
} else {
// File not found in media store DB
Toast.makeText(context, "No Song Found", Toast.LENGTH_SHORT).show();
}
c.close();
}
}, 0);

File delete = new File(songName);
if(delete.exists()){
if(delete.delete()) {
//send broadcast to SongFragment to remove item from reycler View
arrayList.remove(pos);
songPath.remove(pos);
songThumb.remove(pos);
artistName.remove(pos);
songArt.remove(pos);
notifyItemRemoved(pos); //Remove item from the list
notifyItemRangeChanged(pos, arrayList.size());
// songViewHolder.itemView.setVisibility(View.GONE); //tried it but not working
//Optional
Intent intent = new Intent();
intent.setAction(SongFragment.deteleSong);
intent.putExtra("position",pos);
context.sendBroadcast(intent);
}
else
Toast.makeText(context, "Error while deleting File.", Toast.LENGTH_SHORT).show();
}

}
@Override
public int getItemCount() {
return allSongs.size();
}
}

最佳答案

这真是令人困惑的代码。为什么你有所有这些简单对象的列表(arrayList、songPath、songThumb、artistName、songArt),它们在哪里定义,为什么这些列表中的一些被复制到数组,而你还有一个复杂的 SongObject 带有标题、作者、封面成员的对象?

我认为数据的困惑处理是您问题的核心。

您的适配器服务的列表或数组是什么?从适配器构造函数的设计方式以及 getItemCount() 的设计方式来看,很明显您希望 allSongs 在您的适配器中发挥核心作用。但是,在构造函数中,您制作了 allSongs 的浅拷贝。更糟糕并立即导致您描述的症状的是,在您的 deleteSong 方法中,您没有从 allSongs 中删除项目,而是从所有其他列表中删除项目。但是,您的 ViewHolder 持有 allSongsSongObject 对象的成员 ...

要做什么?

  1. 清理您的数据。创建一个更复杂的 SongObject 类(包含所有必需的成员)并将您的数据放入 SongObject 的单个 List 中。

  2. 将此列表传递给适配器的构造函数(就像您现在所做的那样)并制作列表的深拷贝(就像您现在不做的那样)。

  3. 在您的 deleteSong 方法中,通过从列表中删除选定的 SongObject 来删除它,如下所示:

    allSongs.remove(pos);

    然后调用:

    notifyDataSetChanged();

关于android - 为什么 notifyItemRemoved(getAdapterPosition());不管用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47415209/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com