显示来自 Recyclerview 单击项目的图像

Display Image from clicked item of Recyclerview

我正在尝试从已经填充的 recyclerview 中获取图像字符串,以便我可以在另一个 activity 的图像视图中显示该图像。在这里,我使用 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 中。我想获取图像(存储在 elements 中)的路径(url),以便我可以在另一个 activity 中显示该图像。我尝试使用以下方法从 arrayList 中检索 url:

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

但是抛出IndexOutOfBound异常,说index(pos)无效,arrayList的size为0,不知道为什么说list有size 0,而 Recyclerview 得到 pouplated 并显示我使用 jsoup 解析的数据。请帮帮我,我被困了三天。

好的,完整的代码在这里: 这是显示 recyclerview

的主要 activity
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);
}

}

取景器:

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

}

罪魁祸首是:

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

您实际上是在创建一个新的 AsyncTask - 如果您尝试从新的 AsyncTask 中的 arrayList 获取一个元素,很明显列表是空的,因为任务填充doInBackground() 方法中的列表,它还没有被执行。

解法:

在您的 onCreate 方法中,创建您的 getDataAsyncTask 并在成员变量中保留对它的引用。 然后,当任务完成执行并调用 onPostExecute(Void aVoid) 时,设置一个标志来指示该事实。 接下来,在您的 onClickListener 中,引用 相同的 任务,但仅当 asyncTaskFinished 标志设置为 true 时才执行代码:

public class RestaurantsAndCafesActivity 扩展 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;

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

在异步任务中:

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

    asyncTaskFinished = true;
}

请注意,这是一种对现有代码进行最小更改的解决方案,但我建议采用不同的方法 - 将列表保留在 AsyncTask 中有点难看,更好的方法是从 doInBackground return ,并在 onPostExecute 中,将其传递给适配器(同时不在任务中保留对它的 class-scope 引用),当您需要访问列表中的元素时,只需引用适配器,而不是您的 AsyncTask:

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