2015-09-08 65 views
0

我試圖從recyclerview中獲取圖像字符串,該圖像字符串已被填充,以便我可以在另一個活動的imageview上顯示圖像。在這裏,我用jsoup得到圖片的路徑(URL):從Recyclerview的點擊項顯示圖像

org.jsoup.nodes.Document document = Jsoup.connect(URL).get(); 
       for(Element e : document.select("img[src]")) 
       { 
        Elements imgScr = e.select("img[src]"); 
        String elements = imgScr.attr("src"); 
        String text = imgScr.attr("alt"); 
        String desc = imgScr.attr("title"); 

        arrayList.add(new FeedItem(text, elements, desc)); 
       } 

elements變量,然後將其存儲到ArrayList中。我想獲取圖像的路徑(url)(存儲在elements),以便我可以在另一個活動中顯示該圖像。我試圖用這個方法來檢索arrayList該URL:

public String getImageUrl(int pos) 
    { 
     return arrayList.get(pos).getThumb(); 
    } 

IndexOutOfBound拋出異常,說指數(POS)是無效的和arrayList大小爲0。我不知道爲什麼是說這個列表的大小爲0,而Recyclerview被挖掘並顯示我使用jsoup解析的數據。請幫幫我,我堅持了三天。

好了完整的代碼是在這裏: 這主要活動足見recyclerview

public class RestaurantsAndCafesActivity extends Activity { 

public static final String URL = "http://192.168.8.102:80/jay.html"; 

private RecyclerView mRecyclerView; 
private RCRecyclerAdapter adapter; 
public String imgUrl; 
//public List<FeedItem> feedItemList; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.reyclerview_layout); 

    /* Initialize RecyclerView */ 
    mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view); 
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); 

    //parseResult(); 

    new getDataAsyncTask().execute(); 

    final GestureDetector mGestureDetector = new GestureDetector(RestaurantsAndCafesActivity.this, new GestureDetector.SimpleOnGestureListener() { 

     @Override public boolean onSingleTapUp(MotionEvent e) { 
      return true; 
     } 

    }); 


    mRecyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() { 
     @Override 
     public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) { 
      View child = recyclerView.findChildViewUnder(motionEvent.getX(),motionEvent.getY()); 
      if(child!=null && mGestureDetector.onTouchEvent(motionEvent)){ 

       Toast.makeText(RestaurantsAndCafesActivity.this,"Clicked Number "+recyclerView.getChildPosition(child), Toast.LENGTH_SHORT).show(); 
       imgUrl = new getDataAsyncTask().getImageUrl(recyclerView.getChildPosition(child)); 
       Intent intent = new Intent(RestaurantsAndCafesActivity.this, GetReviewActivity.class); 
       intent.putExtra("Imgurl" ,imgUrl); 
       startActivity(intent); 
       return true; 
      } 
      return false; 
     } 

     @Override 
     public void onTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) { 

     } 
    }); 
} 
public class getDataAsyncTask extends AsyncTask<Void,Void,Void>{ 
    ArrayList<FeedItem> arrayList = new ArrayList<>(); 

    public String getImageUrl(int pos) 
    { 
     return arrayList.get(pos).getThumb(); 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 
     try { 
       org.jsoup.nodes.Document document = Jsoup.connect(URL).get(); 
       for(Element e : document.select("img[src]")) 
       { 
        Elements imgScr = e.select("img[src]"); 
        String elements = imgScr.attr("src"); 
        String text = imgScr.attr("alt"); 
        String desc = imgScr.attr("title"); 

        arrayList.add(new FeedItem(text, elements, desc)); 
       } 
      } 
     catch(IOException e) 
      { 
      e.printStackTrace(); 
      } 
     return null; 
    } 

    ProgressDialog progressDialog; 
    @Override 
    protected void onPreExecute() 
    { 
     progressDialog = ProgressDialog.show(RestaurantsAndCafesActivity.this,"Loading","Please Wait",true,false); 
    } 
    @Override 
    protected void onPostExecute(Void aVoid) { 
     progressDialog.dismiss(); 
     adapter = new RCRecyclerAdapter(getApplicationContext(),arrayList); 
     mRecyclerView.setAdapter(adapter); 
    } 

} 

}

這些適配器,viewholder和數據類:

public class RCRecyclerAdapter extends RecyclerView.Adapter<RCRecyclerViewListRowHolder> { 


private List<FeedItem> feedItemList; 
private Context mContext; 

public RCRecyclerAdapter(Context context, List<FeedItem> feedItemList) { 
    this.feedItemList = feedItemList; 
    this.mContext = context; 
} 

@Override 
public RCRecyclerViewListRowHolder onCreateViewHolder(ViewGroup viewGroup, int i) { 
    View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.restaurants_cafes_layout_card, null); 
    RCRecyclerViewListRowHolder mh = new RCRecyclerViewListRowHolder(v); 

    return mh; 
} 

@Override 
public void onBindViewHolder(RCRecyclerViewListRowHolder RCRecyclerViewListRowHolder, int i){ 

    FeedItem feedItem = feedItemList.get(i); 

    Picasso.with(mContext).load(feedItem.getThumb() 
    ).error(R.drawable.placeholder).placeholder(R.drawable.placeholder).into(RCRecyclerViewListRowHolder.thumbnail); 
    RCRecyclerViewListRowHolder.title.setText(feedItemList.get(i).title); 
    RCRecyclerViewListRowHolder.desc.setText(feedItemList.get(i).desc); 
} 

@Override 
public int getItemCount() { 
    return (null != feedItemList ? feedItemList.size() : 0); 
} 

}

viewholder:

public class RCRecyclerViewListRowHolder extends RecyclerView.ViewHolder { 
public ImageView thumbnail; 
public TextView title; 
public TextView desc; 
//Context context; 

public RCRecyclerViewListRowHolder(View view) { 
    super(view); 
    this.thumbnail = (ImageView) view.findViewById(R.id.thumbnail); 
    this.title = (TextView) view.findViewById(R.id.title); 
    this.desc = (TextView) view.findViewById(R.id.desc); 
} 

}

數據:

public class FeedItem { 

public String title; 
public String thumb; 
public String desc; 

public FeedItem(String title, String thumb , String desc) { 
    this.title = title; 
    this.thumb = thumb; 
    this.desc = desc; 
} 

public String getThumb() { 
    return thumb; 
} 

}

+0

您發佈的代碼不足以發現該錯誤。請參閱[最小化,完整和可驗證](http://stackoverflow.com/help/mcve) – maciekjanusz

+0

@invariant好吧,我編輯了帖子,添加了recyclerview的完整代碼。請檢查一下。 –

+0

好吧,我發佈了答案 – maciekjanusz

回答

0

這裏是罪魁禍首:

imgUrl = new getDataAsyncTask().getImageUrl(recyclerView.getChildPosition(child)); 

你實際上是在創建一個新的AsyncTask - 如果你嘗試從t獲得元素他arrayList裏面新的AsyncTask很明顯這個列表是空的,因爲任務在其doInBackground()方法中填充列表,並且它沒有被執行。

解決方案:

在你onCreate方法,創建getDataAsyncTask,並保持在一個成員變量的引用。 然後,當任務完成其執行並調用onPostExecute(Void aVoid)設置一個標誌指示該事實。 接下來,在你的onClickListener,參考相同任務,但執行只有在asyncTaskFinished標誌被設置爲true代碼:

公共類RestaurantsAndCafesActivity延伸活動{

public static final String URL = "http://192.168.8.102:80/jay.html"; 

private RecyclerView mRecyclerView; 
private RCRecyclerAdapter adapter; 
public String imgUrl; 
//public List<FeedItem> feedItemList; 

private getDataAsyncTask myAsyncTask; 
private volatile boolean asyncTaskFinished = false; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.reyclerview_layout); 

    /* Initialize RecyclerView */ 
    mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view); 
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); 

    //parseResult(); 

    myAsyncTask = new getDataAsyncTask(); 
    myAsyncTask.execute(); 

    ... 


mRecyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() { 
     @Override 
     public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) { 
      View child = recyclerView.findChildViewUnder(motionEvent.getX(),motionEvent.getY()); 
      if(child!=null && mGestureDetector.onTouchEvent(motionEvent)){ 

      if(asyncTaskFinished) { 
       Toast.makeText(RestaurantsAndCafesActivity.this,"Clicked Number "+recyclerView.getChildPosition(child), Toast.LENGTH_SHORT).show(); 
       imgUrl = myAsyncTask.getImageUrl(recyclerView.getChildPosition(child)); 
       Intent intent = new Intent(RestaurantsAndCafesActivity.this, GetReviewActivity.class); 
       intent.putExtra("Imgurl" ,imgUrl); 
       startActivity(intent); 
       return true; 
      } 
     return false; 
     } 
    } 

在的AsyncTask:

@Override 
protected void onPostExecute(Void aVoid) { 
    progressDialog.dismiss(); 
    adapter = new RCRecyclerAdapter(getApplicationContext(),arrayList); 
    mRecyclerView.setAdapter(adapter); 

    asyncTaskFinished = true; 
} 

請注意,這是一個解決方案,使您的現有代碼的最小變化,但我會建議一個不同的方法 - 保持lis t在AsyncTask中有點醜陋,更好的方法是將它從doInBackground中返回,並在onPostExecute中將它傳遞給適配器(而不是在任務中保留一個類作用域引用),並且當你需要訪問一個元素列表中,只需引用適配器,而不是您的AsyncTask:

imgUrl = adapter.getList().get(recyclerView.getChildPosition(child)).getThumb(); 
+0

謝謝@invariant,你說的對,'doInBackground()'的列表是空的。我簡單地使用另一個'ArrayList'並將其等同於'onPostExeute()'方法中的'arrayList',然後用它來獲取'url'。 –