У меня есть настраиваемый адаптер GridView
, который принимает объект AudioGridItem
как параметр в его конструкторе. Таким образом, в основном каждый объект имеет 2 ImageView
и 1 TextView
. Когда я удаляю позицию сетки, используя прослушиватель длинного клика, он должен стереть файл (на SD-карте), а затем поместить местозаполнитель на место предыдущего изображения (Uri
). Он также должен установить TextView
на пустой String
. Но это не работает. Обновление ImageView
s, но заголовок файла TextView
все еще задерживается в старом месте. Это приводит к тому, что все в ArrayList
перемещается вверх по пятну, но заголовки файла все еще находятся в старом месте. Тем не менее, с любопытством, когда я переключаюсь на вкладку с фотографией, вернусь к моей вкладке аудио, TextView
обновляется правильно (но он не будет обновляться при переключении на вкладку видео или записи, странно.)TextView в пользовательском адаптере GridView не обновляется, но ImageView делает
Я действительно понимаю как мой адаптер, так и мой ArrayList
, прежде чем перезагружать все (перезапустите AsyncTask
).
Я видел другие сообщения здесь об этой проблеме, но не нашел ничего, что сработает для меня. This один говорит об использовании права TextView
, но у меня только один, и я использую его правильно. Тем не менее, какой-то другой код с моим TextView
, вероятно, неверен? Это единственное, что я могу придумать, так как я использую notifyDataSetChanged()
повсюду, поэтому я знаю, что обновлен мой адаптер (плюс смена s, так что это подсказка). Логикой я использую в моем долгом клике слушателя является:
Удалить файл в положении на SD карте
Очистить мой и мой адаптер и список (затем вызвать
notifyDataSetChanged()
)Reload с SD-карты с нуля по телефону
AsyncTask
снова
Есть идеи? Как вы можете видеть на фотографии, выделенные значки - это те, которые имеют звуковой файл и прикрепляемый к их ImageView
s (которые воспроизводятся правильно), но более темные значки - это те, которые являются заполнителями, и файл, который я пытался длинный щелчок для удаления, показывает значок заполнителя (как он должен), но также и этот затяжной заголовок в TextView
. Как мне избавиться от этого?
AudioTab.java
package org.azurespot.cutecollection.audiotab;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.GridView;
import org.azurespot.R;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
/**
* Created by mizu on 2/8/15.
*/
public class AudioTab extends Fragment {
private GridView gridView;
private GridViewAudioAdapter audioAdapter;
private ProgressDialog progressDialog;
private String[] numberSDCardFiles = null;
File[] files;
ArrayList<AudioGridItem> audioFiles = new ArrayList<>();
AudioGridItem audioGridItem;
AudioGridItem drawable;
AudioGridItem drawableSound;
MediaPlayer mp;
Uri drawableOff;
String audioTitle;
public AudioTab(){
super();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.audio_tab, container, false);
mp = new MediaPlayer();
// instantiate your progress dialog
progressDialog = new ProgressDialog(getActivity());
// with fragments, make sure you include the rootView when finding id
gridView = (GridView) v.findViewById(R.id.audio_grid);
// Create the Custom Adapter Object
audioAdapter = new GridViewAudioAdapter(getActivity(), audioFiles);
// Set the Adapter to GridView
gridView.setAdapter(audioAdapter);
if(audioAdapter.getCount() == 0) {
// load contents of SD card through AsyncTask
new AudioDownloaderTask().execute();
}
setupGridViewListener();
return v;
}
private class AudioDownloaderTask extends AsyncTask<Object, Void, AudioGridItem> {
@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog.setMessage("Loading cute collection ...");
//set the progress bar to cancelable on back button
progressDialog.setCancelable(true);
progressDialog.show();
}
@Override
protected AudioGridItem doInBackground(Object... params) {
retrieveAudio();
return null;
}
@Override
protected void onPostExecute(AudioGridItem result) {
progressDialog.dismiss();
// add sound off drawable to replace song files when there are none
for (int i = 0; i < (15 - numberSDCardFiles.length); i++) {
audioAdapter.add(drawable);
}
audioAdapter.notifyDataSetChanged();
}
}
public void retrieveAudio() {
// creates a new AudioGridItem object with this drawable as the source
drawableSound = new AudioGridItem(null, getResources().getDrawable
(R.drawable.ic_sounds_placeholder_on), null);
try {
// gets directory Cute Videos from sd card
File cuteVideosDir = new File(Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_PODCASTS), "Cute Sounds");
// puts list into files Array
files = cuteVideosDir.listFiles();
// get number of files in Cute Sounds directory
numberSDCardFiles = new String[files.length];
for (File singleFile : files) {
// get both audio file and audio title
Uri audioUri = Uri.fromFile(singleFile);
audioTitle = singleFile.getName();
// get sound on drawable from object
Drawable drawableOn = drawableSound.getDrawable();
// since in a loop, sound on drawable will be added same as files
audioGridItem = new AudioGridItem(audioUri, drawableOn, audioTitle);
// add Uri, drawable (sound on) and title to ArrayList
audioFiles.add(audioGridItem);
}
// put sound off drawable into an AudioGridItem object (as Uri, no Drawable or String)
drawableOff = Uri.parse("android.resource://org.azurespot/drawable/"
+ R.drawable.ic_sounds_placeholder);
drawable = new AudioGridItem(drawableOff, null, null);
} catch (Exception e) {
e.printStackTrace();
}
}
private void setupGridViewListener() {
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView,
View item, int pos, long id) {
AudioGridItem currentItem = audioAdapter.getItem(pos);
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){
public void onCompletion(MediaPlayer mediaPlayer){
mediaPlayer.reset();
}
});
if(!(audioAdapter.getItem(pos).equals(drawable))) {
if(currentItem == audioAdapter.getItem(pos)) {
if (mp.isPlaying()) {
mp.reset();
}
else {
Uri soundFile = (audioAdapter.getItem(pos)).getAudio();
try {
mp.setDataSource(getActivity(), soundFile);
mp.prepare();
mp.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
else{
Uri soundFile = (audioAdapter.getItem(pos)).getAudio();
try {
mp.setDataSource(getActivity(), soundFile);
mp.prepare();
mp.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
});
// to delete a Uri item
gridView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> aView, View item,
final int pos, long id) {
mp.reset();
// insures the placeholder drawable is not clickable
if (!(audioAdapter.getItem(pos)).equals(drawable)) {
new AlertDialog.Builder(getActivity())
.setTitle("Delete")
.setMessage("Delete this cute sound?")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// delete from ArrayList first
audioFiles.remove(pos);
// get file name then delete it from SD card
String name = files[pos].getName();
File file = new File(Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_PODCASTS), "Cute Sounds" + "/" + name);
file.delete();
audioGridItem.setAudioTitle(" ");
// after each item delete, replace with default icon, and empty String
audioAdapter.add(new AudioGridItem(drawableOff, null, null));
// clear old list first
audioAdapter.clear();
audioFiles.clear();
audioAdapter.notifyDataSetChanged();
// reload all files, so positioning is right when open it
new AudioDownloaderTask().execute();
Log.d("TAG", "Reached after async runs again.");
}
})
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// do nothing
dialog.cancel();
}
})
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
}
return true;
}
});
}
}
GridViewAudioAdapter.java
package org.azurespot.cutecollection.audiotab;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import org.apache.commons.io.FilenameUtils;
import org.azurespot.R;
import java.util.ArrayList;
/**
* Created by mizu on 2/8/15.
*/
public class GridViewAudioAdapter extends ArrayAdapter<AudioGridItem> {
private TextView audioTitleView;
int position;
ViewHolder holder = null;
Context context;
String rootName;
public GridViewAudioAdapter(Context context, ArrayList<AudioGridItem> audio) {
super(context, 0, audio);
this.context = context;
}
@Override
public View getView(int position, View itemView, ViewGroup parent) {
this.position = position;
if (itemView == null) {
itemView = LayoutInflater.from(getContext())
.inflate(R.layout.audio_tab_item, parent, false);
holder = new ViewHolder();
holder.audioViewFile = (ImageView) itemView.findViewById(R.id.audio_file);
holder.audioViewIcon = (ImageView) itemView.findViewById(R.id.audio_icon);
audioTitleView = (TextView) itemView.findViewById(R.id.audio_title);
// stores holder with view
itemView.setTag(holder);
} else {
holder = (ViewHolder)itemView.getTag();
}
// get position of the item clicked in GridView
final AudioGridItem audioGridItem = getItem(position);
if (audioGridItem != null) {
// getting the Uri from here might give a file or the off drawable
Uri audioUri = audioGridItem.getAudio();
// this will only ever be the on drawable
Drawable drawableOn = audioGridItem.getDrawable();
// set text
String audioTitle = audioGridItem.getAudioTitle();
if (audioTitle != null) {
rootName = FilenameUtils.removeExtension(audioTitle);
audioTitleView.setText(rootName);
} else
audioTitleView.setText(" ");
// set the Uri or drawable into the ImageView slots
holder.audioViewFile.setImageURI(audioUri);
holder.audioViewIcon.setImageDrawable(drawableOn);
// positioning the file Uri in the GridView slot
holder.audioViewFile.setScaleType(ImageView.ScaleType.CENTER_CROP);
holder.audioViewFile.setLayoutParams(new FrameLayout.LayoutParams
(220, 220));
// positioning the drawable icon in the GridView slot
holder.audioViewIcon.setScaleType(ImageView.ScaleType.CENTER_CROP);
holder.audioViewIcon.setLayoutParams(new FrameLayout.LayoutParams
(220, 220));
}
return itemView;
}
public class ViewHolder{
ImageView audioViewFile;
ImageView audioViewIcon;
}
}
AudioGridItem.Java
package org.azurespot.cutecollection.audiotab;
import android.graphics.drawable.Drawable;
import android.net.Uri;
/**
* Created by mizu on 4/26/15.
*/
public class AudioGridItem {
private Uri audio;
private String audioTitle;
Drawable drawableOn;
public AudioGridItem(Uri audio, Drawable drawable, String autoTitle) {
super();
this.audio = audio;
this.drawableOn = drawable;
this.audioTitle = autoTitle;
}
public Uri getAudio() {
return audio;
}
public void setAudio(Uri audio){
this.audio = audio;
}
public Drawable getDrawable(){
return drawableOn;
}
public void setDrawable(Drawable drawable){
this.drawableOn = drawable;
}
public String getAudioTitle(){
return audioTitle;
}
public void setAudioTitle(String audioTitle){
this.audioTitle = audioTitle;
}
}
внутримышечно обратно. Sir/madam, зачем вам «файлы», какие бы ваши «файлы» не могли сделать для вас, «аудиофайлы» могут сделать для вас, это просто кстати, почему вы не вызываете notifydatasetchanged() сразу после 'audioFiles.remove (pos); 'и почему вы также не попадаете на' audioFiles.get (pos) ', чтобы получить свой элемент вместо использования' files' и после 'file.delete()' вы можете добавить это, чтобы проверить, действительно ли оно удалено 'file.exist()', если нет, тогда вы пытаетесь принудительно удалить. и PLS попробуйте позвонить notifydatasetchanged после удаления и строки и посмотреть, делает ли он diff – Elltz
Привет, Elitz! :) Мне нужно использовать мои «файлы», поэтому я также могу удалить его с SD-карты, но получаю только имя и помещаю в «String» ... так как я полагаюсь на перезагрузку всего с нуля. Но я использую 'audioFiles.remove (pos)' в прослушивателе кликов, поэтому я знаю, что я удаляю правильный ... Я добавил 'notifyDataSetChanged()' сразу после того, как вы сказали, но все же такая же проблема. :(Я сделал проверку 'file.exist', и она вернулась как можно скорее. Это действительно странная ошибка. – Azurespot
Да, действительно странно, да, для этого – Elltz