显示来自Recyclerview的已点击项目的图像

时间:2015-09-08 16:37:45

标签: android android-recyclerview

我正在尝试从recyclerview中获取已填充的图像字符串,以便我可以在另一个活动的imageview上显示图像。在这里,我使用jsoup获取图像的路径(url):

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检索该网址:

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

但抛出了IndexOutOfBound异常,说索引(pos)无效且arrayList的大小为0.我不知道为什么它说该列表有大小0,而Recyclerview被pouplated并显示我使用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);
    }

}

}

这些是适配器,视图和数据类:

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;
}

}

1 个答案:

答案 0 :(得分:0)

这是罪魁祸首:

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

您实际上正在创建一个新的AsyncTask - 如果您尝试从新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;
}

请注意,这是一个对现有代码进行微小更改的解决方案,但我建议采用不同的方法 - 将列表保留在AsyncTask中有点难看,更好的方法是从doInBackground返回它,并在onPostExecute中传递它适配器(虽然没有在任务中保持对它的类范围引用),当你需要从列表中访问一个元素时,只需引用适配器,而不是你的AsyncTask:

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