2016-05-10 12 views
0

私はアンドロイドが初めてです。 ImageViewで構成されたGridView を作成しようとしています。画像はflickrからのもので、flickrを検索してJSONレスポンスを受け取るためにflickr APIを使用しています。 JSONデータを解析して画像URLを取得します。 API呼び出しとJSONデータの解析は、BaseAdapterを拡張したFlickrAdapter内で行われます。しかし、問題は私のgetView()メソッドが呼び出されないことです。 stackoverflow for thisを検索し、表示するデータがない場合、getView()は呼び出されません。しかし、私はFlickrAdapterコンストラクタでデータを設定しています。私はメソッド内でいくつかのデバッグテキストを設定しました。データが設定される前にgetCount()が呼び出され、FlickrAdapterコンストラクタの実行が終了する前にgetCount()が呼び出されることがわかりました。したがって、getView()は呼び出されません。 私のFlickrAdapterのコンストラクターメソッドの実行が終了した後に、getCount()メソッドを呼び出せます。 この問題を解決するにはどうすればよいですか?ここで BaseAdapterコンストラクタメソッドの実行が終了する前にgetCount()が呼び出されています

は私BaseAdapterためのコードと、他のクラス

FlickrAdapter.javaある

public class FlickrAdapter extends BaseAdapter { 

public ArrayList<FlickrImage> flickrImagesList; 
private Context context; 

public static FlickrAdapter instance; 
FlickrAdapter(final Context context, String searchText, Activity activity) { 
    this.flickrImagesList = new ArrayList<FlickrImage>(); 
    this.context = context; 
    instance = this; 
    Flickr flickr = new Flickr(searchText, context, activity); 
    //row[0] = inflater.inflate(R.layout.template, null, false); 
    Log.d("URL", flickr.buildApiUrl()); 
    DownloadManager.getJsonResponse(flickr.buildApiUrl(), context, new VolleyCallBack<JSONObject>() { 
     @Override 
     public void onSuccess(JSONObject success) { 
      //Log.d("JSON",success.toString()); 
      try { 
       success = success.getJSONObject("photos"); 
       JSONArray photo = success.getJSONArray("photo"); 

       for (int i = 0; i < photo.length(); i++) { 
        JSONObject tempObject = photo.getJSONObject(i); 
        String result = new StringBuilder("https://farm" + tempObject.get("farm").toString() + 
          ".staticflickr.com/" + 
          tempObject.get("server").toString() + 
          "/" + 
          tempObject.get("id").toString() + 
          "_" + 
          tempObject.get("secret").toString() + 
          "_n.jpg").toString(); 

        FlickrImage image = new FlickrImage(i, result); 
        instance.flickrImagesList.add(image); 

        Log.d("SIZE", String.valueOf(instance.flickrImagesList.size())); 

       } 
      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 
} 

@Override 
public int getCount() { 
    Log.d("COUNT",String.valueOf(flickrImagesList.size())); 
    return flickrImagesList.size(); 
} 

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

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

class ViewHolder { 
    ImageView myImage; 

    ViewHolder(View v) { 
     myImage = (ImageView) v.findViewById(R.id.individulaImage); 
    } 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    View row = convertView; 
    ViewHolder holder = null; 
    if (row == null) { 
     LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     row = inflater.inflate(R.layout.individual_image, parent, false); 
     holder = new ViewHolder(row); 
     row.setTag(holder); 
    } else { 
     holder = (ViewHolder) row.getTag(); 
    } 


    FlickrImage tempImage = flickrImagesList.get(position); 
    Log.d("Address", tempImage.imageName); 

    //ImageView iv = (ImageView) convertView.findViewById(R.id.individulaImage); 

    //Picasso.with(context).load(tempImage.imageName).into(iv); 
    return row; 
}} 

Flickr.java

public class Flickr { 
private StringBuilder urlBuilder = new StringBuilder("https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=e78808f6cf756218d6981fcdf8021f0c&tags="); 
private String apiUrl = ""; 
private Context context = null; 
private Activity activity; 
private String[] individualImageUrl; 
private String keyWord = ""; 

public Flickr(String keyWord, Context context, Activity activity) { 
    this.keyWord=keyWord; 
    this.apiUrl = buildApiUrl(); 
    this.context = context; 
    this.activity = activity; 
    //Log.d("APIURL", this.apiUrl); 
} 

public String buildApiUrl() { 
    String[] temp; 
    StringBuilder sb = new StringBuilder(); 
    temp = this.keyWord.split(" "); 
    for (int i = 0; i < temp.length; i++) { 
     sb.append(temp[i]); 
     if (i != (temp.length - 1)) { 
      sb.append("+"); 
     } 
    } 
    urlBuilder.append(sb); 
    urlBuilder.append("&text="); 
    urlBuilder.append(sb); 
    urlBuilder.append("&format=json&nojsoncallback=1"); 

    return urlBuilder.toString(); 
}} 

FlickrImage.java

public class FlickrImage { 
public int imageId; 
public String imageName; 

FlickrImage(int imageId, String imageURL) { 
    this.imageId = imageId; 
    this.imageName = imageURL; 
    } 
} 

VolleyCallBack.java

public interface VolleyCallBack<T> { 
public void onSuccess(T success); 
} 

DownloadManager.java

public class DownloadManager { 
public static void getJsonResponse(final String Url, Context context, final VolleyCallBack callBack) { 
    JsonObjectRequest flickrJsonRequest = new JsonObjectRequest(Request.Method.GET, Url, null, 
      new Response.Listener<JSONObject>() { 
       @Override 
       public void onResponse(JSONObject response) { 
        callBack.onSuccess(response); 
       } 
      }, 
      new Response.ErrorListener() { 
       public void onErrorResponse(VolleyError error) { 
        error.printStackTrace(); 
       } 
      }); 
    Volley.newRequestQueue(context).add(flickrJsonRequest); 
} 
} 
+0

私は 'AsyncTask'(例えば' onCreate() ')と' onPostExecute() 'でデータを読み込んでデータリスト(あなたの 'flickrImagesList')にプッシュし、 'notifyDatasetChanged()'、試してみる価値があります。 – 0X0nosugar

+0

私はAsyncTaskについて考えていますが、notifyDatasetChanged()には何もありません。私は見て、それを試してみましょう。ありがとう –

+0

@ 0X0nosugar notifyDatasetChanged()は完全に機能しました。ありがとうたくさんの男:) –

答えて

1

あなたのコンストラクターが完了する前に呼び出されていません。あなたのWebコードは別のスレッドで実行され、コンストラクタコードが完了してからgetCountが呼び出されます。 Webコードが完成したら、Successが呼び出されます。

アダプターでネットワークコードを実行することは決してお勧めできません。あなたのアクティビティまたはフラグメントでそれを実行し、アダプタのnotifyDatasetChanged()を呼び出し終えると、

+0

何かを検索すると、デバッグログに次のメッセージが表示されます 05-10 11:15:54.677 22120-22120/com.example.mamun.wp D/COUNT:0 05 -10 11:15:54.677 22120-22120/com.example.mamun.wp D/COUNT:0 05-10 11:15:54.677 22120-22120/com.example.mamun.wp D/COUNT:0 05-10 11:15:56.507 22120-22120/com.example.mamun.wp D/SIZE:1 05-10 11:15:56.507 22120-22120/com.example.mamun.wp D/SIZE: 2 ここで、「COUNT」はgetCount内部に、「SIZE」はAdapterコンストラクタ内に表示されます。しかし、あなたが私に言ったことで、 "サイズ"はいつも "COUNT"より前に印刷されるべきです。 –

+0

あなたが数えたことは、サイズの前に印刷されることがほとんどです。あなたのonSuccessコールバックの前にカウントを実行してください –

+0

私はそれを得ました。私はコールバックの前にデバッグをしていました。しかし、getCount()が呼び出される前に私のcallBackをどのように実行させることができるのかまだ分かりません。それを行う方法はありますか? –

関連する問題