选择 json 对象时 ListView OnItemClickListener 崩溃
Posted
技术标签:
【中文标题】选择 json 对象时 ListView OnItemClickListener 崩溃【英文标题】:ListView OnItemClickListener Crash when selecting json object 【发布时间】:2018-06-11 15:12:19 【问题描述】:当我尝试从searchActivity.java
检索要使用的 JSON 对象到searchDetail.java
时,应用程序崩溃。似乎函数getInfo()
导致了这个问题。最初getInfo()
中的list_data的大小为10,但是从searchActivity.java
中调用后,大小变成了0。请问我该怎么做才能解决这个问题?
DataParser.java
public class DataParser extends AsyncTask<Void,Void,Integer>
Context c;
ArrayList<Herb> herb=new ArrayList<>();
ArrayList<HashMap<String, String>> list_data = new ArrayList<HashMap<String, String>>();
HashMap<String,String> data = new HashMap<>();
public DataParser(ListView lv)
this.lv = lv;
public DataParser(Context c, String jsonData, ListView lv)
this.c = c;
this.jsonData = jsonData;
this.lv = lv;
@Override
protected Integer doInBackground(Void... params)
return this.parseData();
@Override
protected void onPostExecute(Integer result)
super.onPostExecute(result);
pd.dismiss();
if(result==0)
Toast.makeText(c,"Unable To Parse",Toast.LENGTH_SHORT).show();
else
//BIND DATA TO LISTVIEW
CustomAdapter adapter=new CustomAdapter(c,herb);
lv.setAdapter(adapter);
private int parseData()
try
JSONArray ja=new JSONArray(jsonData);
JSONObject jo=null;
herb.clear();
Herb Herb;
for(int i=0;i<ja.length();i++)
jo=ja.getJSONObject(i);
String id=jo.getString("h_id");
String name=jo.getString("h_name");
String imageUrl=jo.getString("h_image");
Herb=new Herb();
Herb.setId(id);
Herb.setName(name);
Herb.setImageUrl(imageUrl);
herb.add(Herb);
data.put("id",id);
data.put("name",name);
data.put("imageUrl",imageUrl);
list_data.add(data);
DataStorage.map = getInfo();
return 1;
catch (JSONException e)
e.printStackTrace();
return 0;
public ArrayList<HashMap<String, String>> getInfo()
return this.list_data = list_data;
searchActivity.java
public class searchActivity extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
ListView lv= (ListView) findViewById(R.id.HerbListView);
Downloader dl = new Downloader(searchActivity.this,urlAddress,lv);
dl.execute();
final DataParser dp = new DataParser(lv);
lv.setOnItemClickListener (new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
try
ArrayList<HashMap<String, String>> list_data = DataStorage.map;
String hid = list_data.get(position).get("id");
String name = list_data.get(position).get("name");
String imageUrl = list_data.get(position).get("imageUrl");
Intent intent = new Intent(searchActivity.this, searchDetail.class);
intent.putExtra("id", hid);
intent.putExtra("name", name);
intent.putExtra("imageUrl", imageUrl);
startActivity(intent);
catch (NullPointerException e)
e.printStackTrace();
);
searchDetail.java
public class searchDetail extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_detail);
String name = getIntent().getStringExtra("name");
String imageUrl = getIntent().getStringExtra("imageUrl");
TextView txt1= (TextView) findViewById(R.id.txtHName);
ImageView img= (ImageView) findViewById(R.id.imageHerb);
txt1.setText(name);
Picasso.with(this).load(imageUrl).fit().into(img);
DataStorage.java
public class DataStorage
public static ArrayList<HashMap<String,String>> map = new ArrayList<>();
activity_search_detail.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_>
<RelativeLayout
android:layout_
android:layout_
android:orientation="vertical">
<ImageView
android:id="@+id/imageHerb"
android:layout_
android:layout_
android:layout_centerHorizontal="true"
android:scaleType="fitXY" />
<TextView
android:id="@+id/lblHName"
android:layout_
android:layout_
android:layout_below="@id/imageHerb"
android:paddingTop="10dp"
android:text="Herb Name: " />
<TextView
android:id="@+id/txtHName"
android:layout_
android:layout_
android:layout_below="@id/imageHerb"
android:layout_toEndOf="@id/lblHName"
android:paddingTop="10dp"
android:text="TextView" />
</RelativeLayout>
当前生成的 logcat
java.lang.IllegalStateException: Circular dependencies cannot exist in RelativeLayout
P/S:我在activity_search_detail.xml中找不到任何循环依赖
【问题讨论】:
在 searchActivity 中创建 DataParser 后,什么时候将任何元素放入列表中? 检查我的答案dp.execute();
在点击之前添加这个..
如果完成则更新...
@SantanuSur 当我这样做时应用程序崩溃了。发生这种情况可能是因为当 Downloader 类运行时,DataParser 类也会运行
@TomekK i 将元素绑定到 onPostExecute 函数中的列表视图 lv.setAdapter(adapter)
【参考方案1】:
首先执行 DataParser 类 ..new DataParser( lv).execute()
或者在你的情况下是 dp.execute()
你缺少这个语句。如果你没有执行 AsyncTask 类它不会在 doInBackground()
中执行任何任务。希望它能解决您的问题..dp.getinfo()
将始终返回一个空白列表...创建另一个名为 class holdHashmapList
public static ArrayList<Hashmap<String,String>> map= new ArrayList<>();
的类,并在 dataParser 类中 holdHashmapList.map =getInfo();
和 onItemClick 侦听器中...Arralist<map<>> = holdHashmapList.map;
您正在构建的哈希图将始终包含最后一个对象...在parseData
函数中...所以在data.put("id");
之前只需添加data=new HashMap<>();
【讨论】:
当我这样做时应用程序崩溃。发生这种情况可能是因为当 Downloader 类运行时,DataParser 类也会运行 我添加了崩溃 不懂就问 去DataParser
类去ParseData()
方法然后去getInfo();而不是只写holdHashmapList.map = getInfo();
在这种情况下不要写dp.execute();
@DreamCrusher【参考方案2】:
您必须执行 DataParser(dp) 才能在 SearchActivity 中填充您的 list_data。仅初始化 DataParser 不会填充 list_data。
public class searchActivity extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
ListView lv= (ListView) findViewById(R.id.HerbListView);
Downloader dl = new Downloader(searchActivity.this,urlAddress,lv);
dl.execute();
final DataParser dp = new DataParser(lv);
dp.execute(); // update
lv.setOnItemClickListener (new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long
id)
try
ArrayList<HashMap<String, String>> list_data = dp.getInfo();
String hid = list_data.get(position).get("id");
String name = list_data.get(position).get("name");
String imageUrl = list_data.get(position).get("imageUrl");
Intent intent = new Intent(searchActivity.this, searchDetail.class);
intent.putExtra("id", hid);
intent.putExtra("name", name);
intent.putExtra("imageUrl", imageUrl);
startActivity(intent);
catch (NullPointerException e)
e.printStackTrace();
);
【讨论】:
当我这样做时应用程序崩溃。发生这种情况可能是因为当 Downloader 类运行时,DataParser 类也会运行。以上是关于选择 json 对象时 ListView OnItemClickListener 崩溃的主要内容,如果未能解决你的问题,请参考以下文章
Xamarin.Forms JSON 对象到 Listview
如何在 c# 中使用 JSON 使用 foreach 序列化多个项目?
如何使用 JSON 响应,它为我提供了一个带有对象的数组来设置我的 ListView
如何基于 JSON 对象构建 ListView 并在 onItemClick 之后传递其数据