android - 自定义 GridView 适配器中的 TextView 不会更新,但 ImageView 会更新

标签 android arraylist android-asynctask android-arrayadapter android-gridview

我有一个自定义的 GridView 适配器,它将一个 AudioGridItem 对象作为其构造函数中的一个参数。所以基本上每个对象都有 2 个 ImageView 和 1 个 TextView。当我删除网格位置时,使用长按监听器,它应该删除文件(在 SD 卡上),然后在上一张图像 (Uri) 的位置放置一个可绘制的占位符。它还应将 TextView 设置为空 String。但这不起作用。 ImageView 更新了,但文件的 TextView 标题仍然留在旧位置。这导致 ArrayList 中的所有内容都向上移动了一个位置,但文件的标题仍在旧位置。然而,奇怪的是,当我切换到我的照片选项卡,然后返回到我的音频选项卡时,TextView 会正确更新(但当我切换到视频或写入选项卡时它不会更新,奇怪。)

在重新加载所有内容(重新运行 AsyncTask)之前,我确实清除了适配器和 ArrayList

我在这里看到了关于这个问题的其他帖子,但没有找到对我有用的东西。 This有人谈论使用正确的 TextView,但我只有一个,并且正在正确使用它。也就是说,涉及我的 TextView 的其他一些代码可能不正确?这是我唯一能想到的,因为我到处都使用 notifyDataSetChanged(),所以我知道我的适配器已更新(加上 ImageView 的更改,所以这是一个暗示)。我在长按监听器中使用的逻辑是:

  1. 删除SD卡上位置的文件

  2. 清除我的适配器和列表(然后调用 notifyDataSetChanged())

  3. 再次调用 AsyncTask 从 SD 卡重新加载

有什么想法吗?正如您在照片中看到的,突出显示的图标是那些有声音文件和附加到它们的 ImageView 的可绘制对象(可以正确播放),但较暗的图标是占位符,以及我试图长按以删除的文件,它显示了占位符图标(它应该如此),而且还在 TextView 中显示了那个挥之不去的标题。我该如何摆脱它?

enter image description here

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;

    }

}

最佳答案

嗯,看看这个

在你的GridViewAudioAdapter.java

public class GridViewAudioAdapter extends ArrayAdapter<AudioGridItem> {
private TextView audioTitleView; // look at this madam
int position;

在您的getView 方法中

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);

我没有很好的解释,因为现在我正在整理我的想法,但不同之处在于,您的 ImageViewOk 而不是您的 TextView 所以看看你的 getView 我会把 TextView 声明放在 ViewHolder 所以你的 getView 看起来像这个

holder = new ViewHolder();
holder.audioViewFile = (ImageView)itemView.findViewById(R.id.audio_file);
holder.audioViewIcon = (ImageView)itemView.findViewById(R.id.audio_icon);
holder.audioTitleView=(TextView)itemView.findViewById(R.id.audio_title);

试试看看有没有帮助

关于android - 自定义 GridView 适配器中的 TextView 不会更新,但 ImageView 会更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29932215/

相关文章:

android - 自定义 View 上的自定义监听器的数据绑定(bind)

android - 要像海豚浏览器一样创建隐藏在 View 左侧的侧边栏

list - 排序列表 flutter

java - 服务或线程或异步任务

php - 在 Activity 的 "onCreate"方法中从在线 MySQL DB 获取数据

android - 隐藏在 overflow 中的元素仍然可以在 android 上访问

android - 使 Android 4.0.3 应用程序支持 android 3.0 , 3.2, 4.0

android - 将数组列表从一个 Activity 传递到另一个 Activity

java - ArrayList 输出错误

android - 基本Android AsyncTask,执行doInBackground()时发生错误