我正在尝试从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;
}
}
答案 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();