【问题标题】:GridView Adapter not populating? not populating on time? not being updated in onPostExecute()?GridView 适配器未填充?没有按时填充?没有在 onPostExecute() 中更新?
【发布时间】:2016-10-02 09:07:45
【问题描述】:

我正在构建一个由 GridView 和从 API 提取的图像组成的 UI,我正在使用 ImageListAdapter 和 MovieFragment,当我启动应用程序时,我只是得到一个空屏幕。 我尝试过使用预下载图像列表,它可以工作。 从 API 获取数据是在 AsyncTask 上的,我认为问题出在时间上,事实上 gridview.setAdapter() 被调用得太早了。 这是代码:

public class MainActivity extends AppCompatActivity {

private final String LOG_TAG = MainActivity.class.getSimpleName();


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (savedInstanceState == null) {
        getFragmentManager()
                .beginTransaction()
                .add(R.id.container, new MovieFragment())
                .commit();
    }
}}

公共类 MovieFragment 扩展片段 {

private final String LOG_TAG = MovieFragment.class.getSimpleName();
public ImageListAdapter imageAdapter;
String urlPopular = "https://api.themoviedb.org/3/movie/popular?api_key=";
String urlRatings = "https://api.themoviedb.org/3/movie/top_rated?api_key=";

public MovieFragment() {
};


@Override
public void onStart() {
    super.onStart();
    FetchMovieData movieTask = new FetchMovieData();
    movieTask.execute(urlPopular);
}

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

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.movie_fragment_main, container, false);
    GridView gridview = (GridView) rootView.findViewById(R.id.grid_view);
    Log.d(LOG_TAG, imageAdapter.getCount() +"");
    gridview.setAdapter(imageAdapter);

    gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View v,
                                int position, long id) {
            Toast.makeText(getActivity(), "" + position,
                    Toast.LENGTH_SHORT).show();
        }
    });


    return rootView;
}


public class ImageListAdapter extends ArrayAdapter {
    private Context context;
    private LayoutInflater inflater;

    private String[] imageUrls;

    public ImageListAdapter(Context context, String[] imageUrls) {
        super(context, R.layout.image_item, imageUrls);

        this.context = context;
        this.imageUrls = imageUrls;
        inflater = LayoutInflater.from(context);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Log.d(LOG_TAG, imageUrls[position]);
        if (null == convertView) {
            convertView = inflater.inflate(R.layout.image_item, parent, false);
        }

        Picasso
                .with(context)
                .load(imageUrls[position])
                .fit() // will explain later
                .into((ImageView) convertView);

        return convertView;
    }
}


public class FetchMovieData extends AsyncTask<String,Void,String[][]> {

    private final String LOG_TAG = FetchMovieData.class.getSimpleName();
    @Override
    protected String[][] doInBackground(String... params) {
        String url = params[0];
        if (params.length == 0){
            return null;
        }
        // Will contain the raw JSON response as a string.
        String movieJSON = null;

        try {
            movieJSON = getMovieInfo(url);
        } catch (final IOException e) {
            Log.d(LOG_TAG, "Error closing stream", e);
        }

        try{
            return getMovieDataFromJSON(movieJSON);
        }
        catch (JSONException e){
            Log.d(LOG_TAG, e.getMessage(),e);
            e.printStackTrace();
        }

        //Just in case...
        return null;
    }
    private String getMovieInfo(String myurl) throws IOException{
        HttpURLConnection urlConnection = null;
        InputStream inputStream = null;

        try{
            URL url = new URL(myurl);
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.connect();

            inputStream = urlConnection.getInputStream();
            StringBuffer stringBuffer = new StringBuffer();
            if (inputStream == null){
                return null;
            }

            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

            String line;
            while ((line = reader.readLine()) != null) {
                // Since it's JSON, adding a newline isn't necessary (it won't affect parsing)
                // But it does make debugging a *lot* easier if you print out the completed
                // buffer for debugging.
                stringBuffer.append(line + "\n");
            }

            if (stringBuffer.length() == 0) {
                // Stream was empty.  No point in parsing.
                return null;
            }
            Log.d(LOG_TAG, stringBuffer.toString());
            return stringBuffer.toString();
        }
        finally {
            if(urlConnection != null){
                urlConnection.disconnect();
            }
        }
    }

    private String[][] getMovieDataFromJSON(String jsonObj) throws JSONException{

        JSONObject mainJSON = new JSONObject(jsonObj);

        final String POSTERS = "poster_path";
        final String ORIGINAL_TITLE = "original_title";
        final String SYNOPSIS = "overview";
        final String USER_RATING = "vote_average";
        final String RELEASE_DATE = "release_date";
        final String RESULTS = "results";

        // Building a String[][] of movie info while:
        // movie[][0] = Poster path
        // movie[][1] = Original Title
        // movie[][2] = Synopsis
        // movie[][3] = User Rating
        // movie[][4] = Release Date

        JSONArray movieIndexArray = mainJSON.getJSONArray(RESULTS);
        String[][] movie = new String[20][5];

        for(int i = 0; i < movieIndexArray.length(); i++) {
            JSONObject movieObject = movieIndexArray.getJSONObject(i);
            movie[i][0] = movieObject.getString(POSTERS);
            movie[i][1] = movieObject.getString(ORIGINAL_TITLE);
            movie[i][2] = movieObject.getString(SYNOPSIS);
            movie[i][3] = movieObject.getString(USER_RATING);
            movie[i][4] = movieObject.getString(RELEASE_DATE);
        }

        return movie;
    }

    private String[] buildPosterArray(String[][] result){

        String[] url = new String[20];
        Uri.Builder builtUri = new Uri.Builder();
        builtUri.scheme("http");
        builtUri.authority("image.tmdb.org");
        builtUri.appendPath("t");
        builtUri.appendPath("p");
        builtUri.appendPath("w185");

        for (int i = 0 ; i < result.length ; i++){
            builtUri.appendEncodedPath((result[i][0]));
            builtUri.build();
            url[i] = builtUri.toString();
        }
        return url;

    }
    protected void onPostExecute(String[][] result){
        if(result != null){
            String[] posterArray = buildPosterArray(result);
            imageAdapter = new ImageListAdapter(getActivity(), posterArray);
            Log.d(LOG_TAG, imageAdapter.getCount() +"");
        }
    }


}

}

【问题讨论】:

    标签: java android gridview adapter


    【解决方案1】:

    终于解决了,我用BaseAdapter的扩展代替了ArrayAdapter:

    public class ImageAdapter extends BaseAdapter {
        private Context mContext;
        private String[] moviePath;
    
        public ImageAdapter(Context c, String[] path) {
    
            mContext = c;
            this.moviePath = path;
        }
    
        public int getCount() {
            return moviePath.length;
        }
    
        //Needed due to methods being abstract
        public Object getItem(int position) {return null;}
        public long getItemId(int position) {return 0;}
    
        // create a new ImageView for each item referenced by the Adapter
        public View getView(int position, View convertView, ViewGroup parent) {
            ImageView imageView = (ImageView) convertView;
            if (imageView == null) {
                // if it's not recycled, initialize some attributes
                imageView = new ImageView(mContext);
                imageView.setLayoutParams(new GridView.LayoutParams(500, 500));
                imageView.setPadding(5, 5, 5, 5);
            } else {
                imageView = (ImageView) convertView;
            }
    
            //imageView.setImageResource(mThumbIds[position]);
            Picasso.with(getActivity())
                    .load(moviePath[position])
                    .fit()
                    .into(imageView);
            return imageView;
        }
    }
    

    我还在 onPostExecute() 方法中使用了 setAdapter()。

    谢谢大家的帮助=D

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-17
      • 2013-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多