2015-09-08 134 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'。 –