TextView in custom GridView adapter does not update, but ImageView does

时间:2015-04-29 00:21:01

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

I have a custom GridView adapter that takes an AudioGridItem object as a parameter in its constructor. So basically each object has 2 ImageViews and 1 TextView. When I delete a grid position, using a long click listener, it should erase the file (on SD card) then put a placeholder drawable in the place of the previous image (Uri). It should also set the TextView to an empty String. But this does not work. The ImageViews update, but the TextView title of the file still lingers in the old spot. This results in everything in the ArrayList moving up a spot, yet the titles of the file are still in the old spot. Yet, curiously, when I switch to my photo tab, then return to my audio tab, the TextView updates properly (but it won't update when I switch to the video or write tab, strange.)

I do clear both my adapter and my ArrayList before I reload everything (re-run the AsyncTask).

I have seen other posts on here about this problem, but have not found anything that works for me. This one talks about using the right TextView, but I only have one, and am using it right. That said, some other code involving my TextView is probably incorrect? It's the only thing I can think of since I use notifyDataSetChanged() all over the place, so I know my adapter is updated (plus the ImageViews change, so that's a hint). The logic I am using in my long click listener is to:

  1. Delete the file at position on the SD card

  2. Clear my both my adapter and list (then call notifyDataSetChanged())

  3. Reload from SD card from scratch by calling AsyncTask again

Any ideas? As you can see in the photo, the highlighted icons are the ones that have a sound file and a drawable attached to their ImageViews (which play correctly), but the darker icons are the ones that are placeholders, and the file I tried to long click to delete, shows the placeholder icon (as it should) but also that lingering title in the TextView. How do I get rid of this?

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;

    }

}

1 个答案:

答案 0 :(得分:1)

嗯检查出来

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

我没有一个很好的解释,因为现在我正在收集我的想法,但不同的是,你的ImageView 确定而不是你的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);

尝试看看是否有帮助