2012-11-07 11 views
7

मेरे आवेदन में मुझे यूआरएल से बहुत सारी तस्वीरें डाउनलोड करने और उन्हें ग्रिड व्यू में प्रदर्शित करने की आवश्यकता है। (यह 1-200 चित्रों के बीच हो सकता है)। मैं एक ही समय में सभी तस्वीरें डाउनलोड नहीं करना चाहता हूं। मैंने आलसी डाउनलोडिंग के बारे में पढ़ा और मेरा सवाल यह है: क्या मुझे जेसन का केवल एक हिस्सा मिल सकता है, चित्रों को एक अलग थ्रेड में डाउनलोड करें, और केवल अगर उपयोगकर्ता ग्रिड व्यू को स्क्रॉल करता है, तो मैं जेसन के अन्य हिस्सों को जारी रखूंगा , और इसी तरह?आलसी डाउनलोड छवियों में ग्रिड व्यू

संपादित करें: हाय फिर से। मैं इस ग्रिड व्यू में बहु चयन को कार्यान्वित करना चाहता हूं और मुझे एडाप्टर की getView() विधि में कोड को लागू करने में कठिनाई हो रही है। यह उदाहरण है जिसका मैं उपयोग कर रहा हूं: example। मैं अपने getView में इस कोड को कैसे जोड़ सकते हैं() विधि:

public View getView(int position, View convertView, ViewGroup parent) { 
     CheckableLayout l; 
     ImageView i; 

     if (convertView == null) { 
      i = new ImageView(Grid3.this); 
      i.setScaleType(ImageView.ScaleType.FIT_CENTER); 
      i.setLayoutParams(new ViewGroup.LayoutParams(50, 50)); 
      l = new CheckableLayout(Grid3.this); 
      l.setLayoutParams(new GridView.LayoutParams(GridView.LayoutParams.WRAP_CONTENT, 
        GridView.LayoutParams.WRAP_CONTENT)); 
      l.addView(i); 
     } else { 
      l = (CheckableLayout) convertView; 
      i = (ImageView) l.getChildAt(0); 
     } 

     ResolveInfo info = mApps.get(position); 
     i.setImageDrawable(info.activityInfo.loadIcon(getPackageManager())); 

     return l; 
    } 


public class CheckableLayout extends FrameLayout implements Checkable { 
    private boolean mChecked; 

    public CheckableLayout(Context context) { 
     super(context); 
    } 

    public void setChecked(boolean checked) { 
     mChecked = checked; 
     setBackgroundDrawable(checked ? 
       getResources().getDrawable(R.drawable.blue) 
       : null); 
    } 

    public boolean isChecked() { 
     return mChecked; 
    } 

    public void toggle() { 
     setChecked(!mChecked); 
    } 

} 

मेरी getView() कोड:

public View getView(int position, View convertView, ViewGroup parent) { 
    // TODO Auto-generated method stub 
    ViewHolder holder; 
    View vi = convertView; 

    if(convertView == null) { 
     vi = inflater.inflate(com.egedsoft.instaprint.R.layout.item_clickable, null); 
     holder = new ViewHolder(); 
     holder.imgPhoto = (ImageView)vi.findViewById(com.egedsoft.instaprint.R.id.imageClickable); 
     vi.setTag(holder); 

    } else { 
     holder = (ViewHolder) vi.getTag(); 
    } 


    if (!arrayUrls.get(position).getThumbnailUrl().isEmpty()){ 
     imageLoader.DisplayImage(arrayUrls.get(position).getThumbnailUrl(), holder.imgPhoto); 
    } 


    return vi; 
} 
+0

आप JSON डेटा प्राप्त करने का अनुरोध कैसे कर रहे हैं? स्रोत समर्थन पेजिंग करता है? –

+0

मुझे – user1787773

+0

@ सिद्धार्थ लेले लोड करने के लिए अधिक तस्वीर होने पर स्रोत से "अगला यूआरएल" मिलता है: यदि आप मेरे संपादित प्रश्न को देख सकते हैं तो मैं सराहना करता हूं। आपकी मदद के लिए बहुत बहुत धन्यवाद। – user1787773

उत्तर

37

नहीं है। आप अपने तर्क के लिए इसके कुछ हिस्सों का उपयोग कर सकते हैं। मैं एल्बम छवियों को एक एल्बम से लाने के लिए इसका उपयोग करता हूं। तो मेरी ज़रूरतों से अलग मेरी जरूरतें (मैं मान रहा हूं)। लेकिन फिर, तर्क आपके लिए उपयोग किया जा सकता है।

नोट: यह लंबा होगा।

private class getPhotosData extends AsyncTask<Void, Void, Void> { 

    @Override 
    protected Void doInBackground(Void... arg0) { 

     // CHANGE THE LOADING MORE STATUS TO PREVENT DUPLICATE CALLS FOR 
     // MORE DATA WHILE LOADING A BATCH 
     loadingMore = true; 

     // SET THE INITIAL URL TO GET THE FIRST LOT OF ALBUMS 
     URL = "https://graph.facebook.com/" + initialAlbumID 
       + "/photos&access_token=" 
       + Utility.mFacebook.getAccessToken() + "?limit=10"; 

     try { 

      HttpClient hc = new DefaultHttpClient(); 
      HttpGet get = new HttpGet(URL); 
      HttpResponse rp = hc.execute(get); 

      if (rp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { 
       String queryAlbums = EntityUtils.toString(rp.getEntity()); 

       JSONObject JOTemp = new JSONObject(queryAlbums); 

       JSONArray JAPhotos = JOTemp.getJSONArray("data"); 

       // IN MY CODE, I GET THE NEXT PAGE LINK HERE 

       getPhotos photos; 

       for (int i = 0; i < JAPhotos.length(); i++) { 
        JSONObject JOPhotos = JAPhotos.getJSONObject(i); 
        // Log.e("INDIVIDUAL ALBUMS", JOPhotos.toString()); 

        if (JOPhotos.has("link")) { 

         photos = new getPhotos(); 

         // GET THE ALBUM ID 
         if (JOPhotos.has("id")) { 
          photos.setPhotoID(JOPhotos.getString("id")); 
         } else { 
          photos.setPhotoID(null); 
         } 

         // GET THE ALBUM NAME 
         if (JOPhotos.has("name")) { 
          photos.setPhotoName(JOPhotos.getString("name")); 
         } else { 
          photos.setPhotoName(null); 
         } 

         // GET THE ALBUM COVER PHOTO 
         if (JOPhotos.has("picture")) { 
          photos.setPhotoPicture(JOPhotos 
            .getString("picture")); 
         } else { 
          photos.setPhotoPicture(null); 
         } 

         // GET THE PHOTO'S SOURCE 
         if (JOPhotos.has("source")) { 
          photos.setPhotoSource(JOPhotos 
            .getString("source")); 
         } else { 
          photos.setPhotoSource(null); 
         } 

         arrPhotos.add(photos); 
        } 
       } 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) { 

     // SET THE ADAPTER TO THE GRIDVIEW 
     gridOfPhotos.setAdapter(adapter); 

     // CHANGE THE LOADING MORE STATUS 
     loadingMore = false; 
    } 

} 

यह जब पता लगाने के लिए है:

// HOLD THE URL TO MAKE THE API CALL TO 
private String URL; 

// STORE THE PAGING URL 
private String pagingURL; 

// FLAG FOR CURRENT PAGE 
int current_page = 1; 

// BOOLEAN TO CHECK IF NEW FEEDS ARE LOADING 
Boolean loadingMore = true; 

Boolean stopLoadingData = false; 

इस कोड को ब्लॉक कि छवियाँ की प्रारंभिक सेट को हासिल करेगा है: ;-)

ये वैश्विक घोषणाओं गतिविधि के माध्यम से उपयोग के लिए हैं उपयोगकर्ता ने अंत तक स्क्रॉल किया है और छवियों का नया सेट लाया है:

// ONSCROLLLISTENER 
gridOfPhotos.setOnScrollListener(new OnScrollListener() { 

    @Override 
    public void onScrollStateChanged(AbsListView view, int scrollState) { 

    } 

    @Override 
    public void onScroll(AbsListView view, int firstVisibleItem, 
      int visibleItemCount, int totalItemCount) { 
     int lastInScreen = firstVisibleItem + visibleItemCount; 
     if ((lastInScreen == totalItemCount) && !(loadingMore)) { 

      if (stopLoadingData == false) { 
       // FETCH THE NEXT BATCH OF FEEDS 
       new loadMorePhotos().execute(); 
      } 

     } 
    } 
}); 

और अंत में, यह है मैं कैसे छवियों के अगले सेट लाने:

private class loadMorePhotos extends AsyncTask<Void, Void, Void> { 

    @Override 
    protected Void doInBackground(Void... arg0) { 

     // SET LOADING MORE "TRUE" 
     loadingMore = true; 

     // INCREMENT CURRENT PAGE 
     current_page += 1; 

     // Next page request 
     URL = pagingURL; 

     try { 

      HttpClient hc = new DefaultHttpClient(); 
      HttpGet get = new HttpGet(URL); 
      HttpResponse rp = hc.execute(get); 

      if (rp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { 
       String queryAlbums = EntityUtils.toString(rp.getEntity()); 
       // Log.e("PAGED RESULT", queryAlbums); 

       JSONObject JOTemp = new JSONObject(queryAlbums); 

       JSONArray JAPhotos = JOTemp.getJSONArray("data"); 

       // IN MY CODE, I GET THE NEXT PAGE LINK HERE 

       getPhotos photos; 

       for (int i = 0; i < JAPhotos.length(); i++) { 
        JSONObject JOPhotos = JAPhotos.getJSONObject(i); 
        // Log.e("INDIVIDUAL ALBUMS", JOPhotos.toString()); 

        if (JOPhotos.has("link")) { 

         photos = new getPhotos(); 

         // GET THE ALBUM ID 
         if (JOPhotos.has("id")) { 
          photos.setPhotoID(JOPhotos.getString("id")); 
         } else { 
          photos.setPhotoID(null); 
         } 

         // GET THE ALBUM NAME 
         if (JOPhotos.has("name")) { 
          photos.setPhotoName(JOPhotos.getString("name")); 
         } else { 
          photos.setPhotoName(null); 
         } 

         // GET THE ALBUM COVER PHOTO 
         if (JOPhotos.has("picture")) { 
          photos.setPhotoPicture(JOPhotos 
            .getString("picture")); 
         } else { 
          photos.setPhotoPicture(null); 
         } 

         // GET THE ALBUM'S PHOTO COUNT 
         if (JOPhotos.has("source")) { 
          photos.setPhotoSource(JOPhotos 
            .getString("source")); 
         } else { 
          photos.setPhotoSource(null); 
         } 

         arrPhotos.add(photos); 
        } 
       } 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) { 

     // get listview current position - used to maintain scroll position 
     int currentPosition = gridOfPhotos.getFirstVisiblePosition(); 

     // APPEND NEW DATA TO THE ARRAYLIST AND SET THE ADAPTER TO THE 
     // LISTVIEW 
     adapter = new PhotosAdapter(Photos.this, arrPhotos); 
     gridOfPhotos.setAdapter(adapter); 

     // Setting new scroll position 
     gridOfPhotos.setSelection(currentPosition + 1); 

     // SET LOADINGMORE "FALSE" AFTER ADDING NEW FEEDS TO THE EXISTING 
     // LIST 
     loadingMore = false; 
    } 

} 

और यह SET को सहायक वर्ग और इसके बाद के संस्करण के प्रश्नों से एकत्र GET डेटा है:

public class getPhotos { 

    String PhotoID; 

    String PhotoName; 

    String PhotoPicture; 

    String PhotoSource; 

    // SET THE PHOTO ID 
    public void setPhotoID(String PhotoID) { 
     this.PhotoID = PhotoID; 
    } 

    // GET THE PHOTO ID 
    public String getPhotoID() { 
     return PhotoID; 
    } 

    // SET THE PHOTO NAME 
    public void setPhotoName(String PhotoName) { 
     this.PhotoName = PhotoName; 
    } 

    // GET THE PHOTO NAME 
    public String getPhotoName() { 
     return PhotoName; 
    } 

    // SET THE PHOTO PICTURE 
    public void setPhotoPicture(String PhotoPicture) { 
     this.PhotoPicture = PhotoPicture; 
    } 

    // GET THE PHOTO PICTURE 
    public String getPhotoPicture() { 
     return PhotoPicture; 
    } 

    // SET THE PHOTO SOURCE 
    public void setPhotoSource(String PhotoSource) { 
     this.PhotoSource = PhotoSource; 
    } 

    // GET THE PHOTO SOURCE 
    public String getPhotoSource() { 
     return PhotoSource; 
    } 
} 

आप भी adapter कोड चाहते हैं, करते हैं मुझे पता है। मैं एडाप्टर में Fedor'sLazy Loading विधि का उपयोग करता हूं।

पुhew। उम्मीद है कि इनमें से कोई भी मदद करता है। यदि आपके पास और सवाल है, तो पूछने के लिए स्वतंत्र महसूस करें।:-)

संपादित करें: एडाप्टर कोड कहा:

public class PhotosAdapter extends BaseAdapter { 

    private Activity activity; 

    ArrayList<getPhotos> arrayPhotos; 

    private static LayoutInflater inflater = null; 
    ImageLoader imageLoader; 

    public PhotosAdapter(Activity a, ArrayList<getPhotos> arrPhotos) { 

     activity = a; 

     arrayPhotos = arrPhotos; 

     inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     imageLoader = new ImageLoader(activity.getApplicationContext()); 
    } 

    public int getCount() { 
     return arrayPhotos.size(); 
    } 

    public Object getItem(int position) { 
     return arrayPhotos.get(position); 
    } 

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

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

     ViewHolder holder; 

     View vi = convertView; 
     if(convertView == null) { 
      vi = inflater.inflate(R.layout.photos_item, null); 

      holder = new ViewHolder(); 

      holder.imgPhoto = (ImageView)vi.findViewById(R.id.grid_item_image); 

      vi.setTag(holder); 
      } else { 
      holder = (ViewHolder) vi.getTag(); 
     } 


     if (arrayPhotos.get(position).getPhotoPicture() != null){ 
      imageLoader.DisplayImage(arrayPhotos.get(position).getPhotoPicture(), holder.imgPhoto); 
     } 
     return vi; 
    } 

    static class ViewHolder { 
     ImageView imgPhoto; 

    } 
} 

संपादित करें: जोड़ा चरणों प्रगति दिखाने के लिए लोड करते समय:

आप XML जहां आप इसे ठीक नीचे GridView के लिए एक ProgressBar जोड़ें। वजन के साथ खेलें यदि यह किसी भी समस्या का कारण बनता है।

<LinearLayout 
    android:id="@+id/linlaProgressBar" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:gravity="center" 
    android:orientation="horizontal" > 

    <ProgressBar 
     style="@style/Spinner" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:padding="2dp" /> 
</LinearLayout> 

अपने जावा में, वैश्विक रूप Linearlayout linlaProgressBar घोषित करने और onCreate() में यह डाल सकते हैं और यह के रूप में linlaProgressBar.setVisibility(View.GONE);

दृश्यता सेट और onPreExecute() में इसे इस तरह का उपयोग करें:

@Override 
protected void onPreExecute() { 
    // SHOW THE BOTTOM PROGRESS BAR (SPINNER) WHILE LOADING MORE PHOTOS 
    linlaProgressBar.setVisibility(View.VISIBLE); 
} 

और अंत में जोड़ें, onPostExecute()

// HIDE THE BOTTOM PROGRESS BAR (SPINNER) AFTER LOADING MORE ALBUMS 
linlaProgressBar.setVisibility(View.GONE); 
में
+0

यह वही है जो मुझे चाहिए! मैं अब कोशिश करूँगा। अगर आप एडेप्टर कोड भी पोस्ट कर सकते हैं तो मैं सराहना करता हूं। धन्यवाद! – user1787773

+0

@ user1787773: पोस्ट में 'एडाप्टर' कोड जोड़ा गया है। –

+0

आपको बहुत बहुत धन्यवाद! यह बहुत अच्छा काम कर रहा है। क्या आपको पता है कि ग्रिड के नीचे थोड़ा लोडिंग साइन जोड़ने की कोई संभावना है? (समय लोड होने में कुछ क्षण लग रहे हैं) – user1787773

3

आप एंड्रॉयड प्रलेखन से Using adapter Views और GridView को एक बार देख ले सकते हैं। सबसे महत्वपूर्ण बात यह है कि एडाप्टर विधि getView को स्क्रीन पर दिखाए गए प्रविष्टियों की स्थिति को पास करते हुए, और उपयोगकर्ता स्क्रॉल करते समय अलग-अलग स्थितियों के लिए पूछता है।

करने का आसान तरीका आपके एडाप्टर के getView विधि और AsyncTask पर आवश्यक छवि डाउनलोड करना है।

यह कैसे मैं अपने गतिविधि में कई फ़ोटो लाने है एक example

0

अनुभव से बात करते हुए, स्मृति को उचित रूप से उपभोग करते समय चिकनी स्क्रॉलिंग (और समग्र प्रतिक्रिया) प्राप्त करना मुश्किल है। Lazy load of images in ListView

हम एक कस्टम मालिकाना समाधान के साथ समाप्त हो गया:

यह पहली बार मौजूदा समाधान के लिए देखने के लिए एक अच्छा विचार है, उदाहरण के लिए, यहाँ शुरू होगा। यह एक पृष्ठभूमि धागा है जो बाह्य भंडारण पर केवल अनुरोधों और डाउनलोड और कैश डाउनलोड करता है जो छवियां अभी भी दिखाई दे रही हैं। जब कोई नई छवि आती है, तो दृश्य को सूचित किया जाता है और अपडेट करने के लिए एडाप्टर को सूचित करने का निर्णय लेता है।

यह बैंडविड्थ भी बचाता है, जो कुछ मामलों में महत्वपूर्ण था।

+0

क्या कोई कोड है जिसे मैं लागू करने के लिए कहीं भी देख सकता हूं? धन्यवाद! –

0

मुझे मिला है IceMAN के उत्तर बहुत उपयोगी है, लेकिन मैं भी दो AsyncTasks का उपयोग करने से बचने की सलाह देता हूं और आप इसे आसानी से बना सकते हैं।

आप आवश्यक डेटा, जहाँ आप (एक उदाहरण के रूप में) एक अगर/किसी और शर्त कर सकते हैं लाने के लिए एक सार्वभौमिक विधि बनाने की जरूरत:

 movies = fetchMovie.execute(sort).get(); 
     if (movies == null) { 
      movieList = new ArrayList<>(); 
     } else if (addMovies) { 
      movieList.addAll(movies); 
     } else { 
      movieList = movies; 
     } 

addMovies अपने Onscroll विधि में एक बूलियन है। AsyncTask में क्वेरी पेज यूआरएल और वॉयला में वर्तमान पृष्ठ प्रदान करते हैं - आपने अपना कोड छोटा बना दिया है :)

संबंधित मुद्दे