【问题标题】:How to refresh GridView for Custom Image Adapter?如何为自定义图像适配器刷新 GridView?
【发布时间】:2015-12-28 20:07:52
【问题描述】:

我目前正在从事一个在线 android 学习项目,并面临刷新我的网格视图的问题。

我的应用最初会显示一个包含多张图像的网格。单击菜单中的 刷新按钮 后,GridView 应填充新图像。此外,单击任何图像时,应用程序会转到显示当前图像 URL 的 Detail Activity。

目前,我首先使用我的自定义适配器和毕加索使用示例图像填充 GridView。然后执行一个 AsyncTask 从 JSON 中获取新的图像 URL。必须将这个新的 imageURL 列表提供给我的适配器,以便网格显示新图像。

但是,我无法做到这一点。我的初始网格显示图像,单击这些图像后,我可以按预期在详细活动屏幕上获得它们的 URL。但是,当我单击菜单中的刷新 时,我看不到新图像。我正在尝试在 onPostExecute() 中使用更新的 URL 数组设置适配器。

单击旧图像时,我会在详细信息活动中看到新 URL,但是一旦单击返回,图像仍未更新,并且 URL 会更改回旧图像。有时当我滚动时,新图像会出现,然后应用程序崩溃。

所以基本问题是,即使在获取新 URL 之后,我也无法使用新图像填充 GridView。对此的任何帮助将不胜感激。谢谢,

代码片段:

public class MovieListFragment extends Fragment {
public CustomAdapter customAdapter;
public GridView gv;
public List<String> allImages=new ArrayList<String>();
public List<String> newImages=new ArrayList<String>();
public String LOG_TAG=MovieListFragment.class.getSimpleName();
public int abc=0;
public MovieListFragment() {
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootview= inflater.inflate(R.layout.movie_list_fragment, container, false);


    //Fake Data Creation for 1st time GridView load.
    allImages.add("http://www.pnas.org/site/misc/images/15-01065.500.jpg");
    allImages.add("http://41.media.tumblr.com/78335e84b3b353ad60c335b24a5f267e/tumblr_nz2bke3fJ51rldeoho1_500.jpg");
    allImages.add("http://41.media.tumblr.com/78335e84b3b353ad60c335b24a5f267e/tumblr_nz2bke3fJ51rldeoho1_500.jpg");
    allImages.add("http://41.media.tumblr.com/78335e84b3b353ad60c335b24a5f267e/tumblr_nz2bke3fJ51rldeoho1_500.jpg");
    allImages.add("http://41.media.tumblr.com/78335e84b3b353ad60c335b24a5f267e/tumblr_nz2bke3fJ51rldeoho1_500.jpg");
    allImages.add("http://www.pnas.org/site/misc/images/15-01065.500.jpg");
    allImages.add("http://www.pnas.org/site/misc/images/15-01065.500.jpg");
    allImages.add("http://www.pnas.org/site/misc/images/15-01065.500.jpg");
    allImages.add("http://www.pnas.org/site/misc/images/15-01065.500.jpg");

    //Set Adapter
    gv = (GridView) rootview.findViewById(R.id.gridview);
    customAdapter=new CustomAdapter(getActivity(),allImages);
    gv.setAdapter(customAdapter);

    //On Click Listener
    gv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            Intent intent = new Intent(getActivity(), DetailActivity.class);
            intent.putExtra("imageURL", allImages.get(position).toString());
            startActivity(intent);
        }
    });

    return rootview;
}

//My Custom Adapter
public class CustomAdapter extends BaseAdapter{

    private Context mContext;
    private List<String> myImageList;

    public CustomAdapter(Context c, List<String> finalImageList) {

       mContext = c;
       myImageList=finalImageList;
       notifyDataSetChanged();
   }

   @Override
   public int getCount() {
       return myImageList.size();
   }

   @Override
   public Object getItem(int position) {
       return myImageList.get(position);
   }

   @Override
   public long getItemId(int position) {
       return 0;
   }

   @Override
   public View getView(int position, View convertView, ViewGroup parent) {

       ImageView imageView;
       if (convertView == null) {
           // if it's not recycled, initialize some attributes
           imageView = new ImageView(mContext);
           imageView.setLayoutParams(new GridView.LayoutParams(500, 500));
           imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
         //  imageView.setPadding(2, 2, 2, 2);
       } else {
           imageView = (ImageView) convertView;
       }

       Picasso.with(getActivity())
               .load(myImageList.get(position))
               .into(imageView);

       return imageView;
   }

}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.movie_list_fragment_menu, menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id=item.getItemId();
    if(id==R.id.action_refresh){
        updateMovieList();
        return true;
    }

    return super.onOptionsItemSelected(item);
}

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

private void updateMovieList() {
    FetchMovieDetailsTask fetchMovieDetailsTask=new FetchMovieDetailsTask();
    fetchMovieDetailsTask.execute("Popularity");
}

public class FetchMovieDetailsTask extends AsyncTask<String, Void, String[]>{
    public String LOG_TAG_SECOND=FetchMovieDetailsTask.class.getSimpleName();


    @Override
    protected String[] doInBackground(String... params) {

        HttpURLConnection urlConnection = null;
        BufferedReader reader = null;

        // Will contain the raw JSON response as a string.
        String movieDetailJsonStr = "";
        String filterType = "";
        String api_key = "e77c4d231a4c24ffe0357b694751910c";

        if (params[0].equals("Popularity")) {
            filterType = "vote_average.desc";
        } else if (params[0].equals("Rating")) {
            filterType = "popularity.desc";
        }

        try {

            final String MOVIEDETAIL_BASE_URL = "https://api.themoviedb.org/3/discover/movie?";
            final String FILTER_PARAM = "sort_by";
            final String APP_KEY_PARAM = "api_key";

            Uri builtUri = Uri.parse(MOVIEDETAIL_BASE_URL).buildUpon()
                    .appendQueryParameter(FILTER_PARAM, filterType)
                    .appendQueryParameter(APP_KEY_PARAM, api_key).build();


            URL url = new URL(builtUri.toString());
            Log.v(LOG_TAG_SECOND, builtUri.toString());

            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.connect();

            // Read the input stream into a String
            InputStream inputStream = urlConnection.getInputStream();
            StringBuffer buffer = new StringBuffer();
            if (inputStream == null) {
                // Nothing to do.
                return null;
            }
            reader = new BufferedReader(new InputStreamReader(inputStream));

            String line;
            while ((line = reader.readLine()) != null) {

                buffer.append(line + "\n");
            }

            if (buffer.length() == 0) {
                // Stream was empty.  No point in parsing.
                return null;
            }
            movieDetailJsonStr = buffer.toString();
            Log.v(LOG_TAG_SECOND, " Movie Details JSON " + movieDetailJsonStr);

            try {
                getMovieDetailsFromJSON(movieDetailJsonStr);
            } catch (JSONException e) {
                e.printStackTrace();
            }


        } catch (IOException e) {
            Log.e(LOG_TAG, "Error ", e);
            return null;

        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (final IOException e) {
                    Log.e(LOG_TAG, "Error closing stream", e);
                }
            }
        }
        return null;
    }


    private String[] getMovieDetailsFromJSON(String movieDetailsJSON) throws JSONException{

        final String MOV_TITLE = "title";
        final String MOV_OVERVIEW = "overview";
        final String MOV_RATING = "vote_average";
        final String MOV_POSTER_PATH = "poster_path";

        final String MOV_LIST = "results";

        JSONObject movieListJSON = new JSONObject(movieDetailsJSON);
        JSONArray movieListArray = movieListJSON.getJSONArray(MOV_LIST);

        int numOfMovies=8;
        allImages.clear();
        String[] resultStrs = new String[numOfMovies];
        String[] resultPosters= new String[numOfMovies];

        for(int i=0; i<numOfMovies; i++){

            String title;
            String overview;
            String rating;
            String poster_path;

            JSONObject movieDetails=movieListArray.getJSONObject(i);

            overview=movieDetails.getString(MOV_OVERVIEW);
            title=movieDetails.getString(MOV_TITLE);
            rating=movieDetails.getString(MOV_RATING);
            poster_path=movieDetails.getString(MOV_POSTER_PATH);

            resultStrs[i]=title + "\n" + overview + "\n" + rating + "\n" + poster_path;
            resultPosters[i]=poster_path;
            makePosterURL(resultPosters[i]);


        }

        for (String s : resultStrs) {
            Log.v(LOG_TAG_SECOND, "MOVIE DETAILS: " + s);
        }
        return resultStrs;


    }

    private void makePosterURL(String resultPoster) {
        String baseURL="http://image.tmdb.org/t/p/w500";
        //resultPoster=resultPoster.replace("\\", "");
        String finalURL="";
        finalURL=baseURL+resultPoster;
        Log.v(LOG_TAG_SECOND, "Final Poster URL " + finalURL);
        allImages.add(finalURL);
    }

    @Override
    protected void onPostExecute(String[] strings) {
        if(strings!=null){
            customAdapter=new CustomAdapter(getActivity(), allImages);
            gv.invalidateViews();
            gv.setAdapter(customAdapter);
        }
       // super.onPostExecute(strings);
    }
}

【问题讨论】:

    标签: android gridview android-adapter


    【解决方案1】:

    因为您始终在您的doInBackground() 中使用return null,所以代码永远不会使用更新的灯来重置您的适配器。要更新您的更新程序,您只需调用

    adapter.notifyDataSetChanged();
    

    在您的onPostExecuted()
    顺便说一句,您的 getMovieDetailsFromJSON() 返回类型 String[] 与 doInBackgound() 一样无用,您应该将其设为 void,因为您不使用该值。

    【讨论】:

    • 谢谢。我忘记更新“return getMovieDetailsFromJSON(movieDetailJsonStr);”在我的 doInBackground() 方法中。我更新了相同的内容,现在图像刷新了。但是,当我单击并进入 DetailActivity 然后返回时,我会看到旧图像。我错过了什么吗?
    • 另外,当我在 DetailActivity 中填充其他详细信息时,我将使用在后续步骤中返回的 String[]。非常感谢。
    • 不客气 :) 回看旧图像是什么意思?只有旧图像还是新旧图像?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多