2016-05-17 13 views
2

次のアンドロイドアプリを作成しようとしています:APIからのデータをGridviewに取り込む方法は?

1)「映画DB」APIに接続して、人気のある映画が最も多いJSONを持ってきてください。

2)そのJSONから、人気のあるすべての映画のポスター(小さな画像)へのリンクを抽出します。

3)Picasaのライブラリを使用して、画像をGridviewに配置します。

手順1と2は正常に動作しています。 3はほぼそこにありますが、私は仕事の非同期タイプに問題があります。

投稿者のリストをハードコードする必要がありますが、Gridviewがうまくいきますが、私がバックグラウンドジョブを実行すると、データが準備される前にビューが作成されていると思っています。 Viewが取得できない、またはレンダリングしないしたがって、アクティビティは空白になります。

MainFragment.java

package com.example.android.popmovies; 

import android.content.Context; 
import android.os.AsyncTask; 
import android.os.Bundle; 
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.BaseAdapter; 
import android.widget.GridView; 
import android.widget.ImageView; 

import com.squareup.picasso.Picasso; 

import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.net.HttpURLConnection; 
import java.net.URL; 
import java.util.ArrayList; 
import java.util.List; 

public class MainFragment extends Fragment { 

    // the array to populate with data from the API 
    private List moviesArray= new ArrayList(); 

    public MainFragment() { 
     // Required empty public constructor 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     Connection connection = new Connection(); 
     connection.execute(); 
    } 

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

     View rootView = inflater.inflate(R.layout.fragment_main, container, false); 

     GridView gridView = (GridView) rootView.findViewById(R.id.grid_view_id);     
     gridView.setAdapter(new CustomAdapter(this.getContext(), moviesArray)); 

     return rootView; 
    } 

    public class CustomAdapter extends BaseAdapter{ 

     private Context context; 
     private List items; 

     public CustomAdapter(Context context, List items){ 
      super(); 
      this.context = context; 
      this.items = items; 
     } 

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

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

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

     @Override public View getView(int position, View convertView, ViewGroup parent) { 
      ImageView img; 
      if (convertView == null) { 
       img = new ImageView(context); 
       img.setPadding(0,5,0,0); 
       convertView = img; 
      } else { 
       img = (ImageView) convertView; 
      } 

      Picasso.with(context) 
        .load((String) items.get(position)) 
        .into(img); 
      return convertView; 
     } 
    } 

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

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

     private String[] getPosterDataFromJson(String moviesJsonStr) throws JSONException { 

      String[] posters = new String[moviesJsonStr.length()]; 
      // These are the names of the JSON objects that need to be extracted 
      final String RESULTS = "results"; 
// 
      // convertimos el JSON en un array 
      JSONObject moviesJson = new JSONObject(moviesJsonStr); 
      JSONArray moviesArray = moviesJson.getJSONArray(RESULTS); 

      for(int i = 0; i < moviesArray.length(); i++) { 

       String image; 

       JSONObject poster = moviesArray.getJSONObject(i); 
       image = poster.getString("poster_path"); 
       posters[i] = image; 

      } 
      return posters; 
     } 

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

      HttpURLConnection urlConnection = null; 
      BufferedReader reader = null; 

      // Will contain the raw JSON response as a string. 
      String moviesJsonStr; 

      try { 
       // Construct the URL 
       String baseUrl = "http://api.themoviedb.org/3/movie/popular"; 
       String apiKey = "?api_key=" + BuildConfig.POP_MOVIES_API_KEY; 
       URL url = new URL(baseUrl.concat(apiKey)); 

       // Create the request and open the connection 
       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) { 
        // 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. 
        buffer.append(line + "\n"); 
       } 

       if (buffer.length() == 0) { 
        // Stream was empty. No point in parsing. 
        return null; 
       } 

       // Paso todo el JSON a una variable 
       moviesJsonStr = buffer.toString(); 

       // Extraigo del JSON lo que me interesa y lo guardo en un vector 
       String[] datos = getPosterDataFromJson(moviesJsonStr); 

       // Verificamos que haya algo en el vector 

       //Log.v(LOG_TAG, "Estoy en CONNECTION y el tamaño de DATOS es: " + Integer.toString(datos.length)); 
       for (int i=0; i<datos.length; i++){ 
        while(datos[i] != null){ 
         Log.v(LOG_TAG, datos[i]); 
         break; 
        } 

       } 

       return datos; 

      } catch (IOException e) { 
       Log.e(LOG_TAG, "Error ", e); 
       return null; 
      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 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; 
     } 

     @Override 
     protected void onPostExecute(String[] result) { 
      if (result != null) { 
       for(String posterStrings : result) { 
        while(posterStrings != null){       
         String direccion = "http://image.tmdb.org/t/p/" + "w185/" + posterStrings; 
         Log.v(LOG_TAG, direccion); 
         moviesArray.add(direccion); 
         break; 
        } 
       } 
      } 
     } 
    } 
} 

問題は、データがビューを作成した後に到着したが、「ビュー「を知らせる」こと - 私ができていませんねえ、あなたが得たことであることはほぼ確信 - 私いくつかのデータを世話する "。

ありがとうございます。私の英語をお許しください。

+0

コール 'ダウンロードが完了 – EpicPandaForce

答えて

2

更新されたアイテムのリストについては、アダプターに知らせる必要があります。 updateMoviesメソッドのようなものをアダプタに追加し、それをonPostExecuteから呼び出します。そのような :

CustomAdapter mAdapter; 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    ... 
    mAdapter = new CustomAdapter(this.getContext(), moviesArray); 
    gridView.setAdapter(mAdapter); 
    ... 
} 

public class CustomAdapter extends BaseAdapter{ 
    ... 
    public void updateMovies(List items) { 
     mItems = items; 
     notifyDataSetChanged(); 
    } 
    ... 
} 

public class Connection extends AsyncTask<Void, Void, String[]> { 
    ... 
    @Override 
    protected void onPostExecute(String[] result) { 
     if (result != null) { 
      for(String posterStrings : result) { 
       while(posterStrings != null){       
        String direccion = "http://image.tmdb.org/t/p/" + "w185/" + posterStrings; 
        Log.v(LOG_TAG, direccion); 
        moviesArray.add(direccion); 
        break; 
       } 
      } 
      mAdapter.updateMovies(moviesArray); 
     } 
    } 
    ... 
} 
+0

あるとき()'アダプタにnotifyDatasetChangedそして、フランケンシュタイン博士は言った: "It's生きています!"。完璧な作品、ありがとう! –

+0

それは素晴らしい作品:) –

関連する問題