Android如何在数据进入后设置listview适配器
Posted
技术标签:
【中文标题】Android如何在数据进入后设置listview适配器【英文标题】:Android how can i set listview adapter when data comes in after it 【发布时间】:2016-01-11 19:27:38 【问题描述】:我在正确设置列表视图适配器时遇到了一些问题。我有一个列表视图,它从 AsyncTask 获取数据,然后从 Json 格式的 Web 服务获取其信息,并且该数据仅在 AsyncTask 的 OnPostExecute 方法中可用,我在那里设置了我的适配器。问题是新信息频繁出现,并且每次都设置适配器会导致性能不佳。当信息进入 AsyncTask 时,如何设置适配器一次?这是我的活动...
public class Myprofile extends Activity
String URI_URL;
Integer page;
ProgressBar pb;
ListView mm;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.myprofile);
URI_URL = getResources().getString(R.string.PathUrl) + "/api/myprofile";
page=0;
new Myprofile_Async().execute();
// Listview for adapter
mm= (ListView)findViewById(R.id.myprofiles);
// Listview to use inside scroll event
final ListView lv=(ListView)findViewById(R.id.myprofiles);
lv.setOnScrollListener(new AbsListView.OnScrollListener()
@Override
public void onScrollStateChanged(AbsListView view, int scrollState)
// fires off when scroll close to bottom
if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE && (lv.getLastVisiblePosition() - lv.getHeaderViewsCount() - lv.getFooterViewsCount()) >= (view.getCount() - 1))
new Myprofile_Async().execute();
@Override
public void onScroll(AbsListView absListView, int i, int i1, int i2)
);
public class Myprofile_Async extends AsyncTask<String,String,String>
HttpURLConnection conn;
URL url;
String result="";
DataOutputStream wr;
int id;
@Override
protected void onPreExecute()
super.onPreExecute();
pb=(ProgressBar)findViewById(R.id.progressBar);
pb.setVisibility(View.VISIBLE);
id= getIntent().getExtras().getInt("id");
// page Int is used to keep count of scroll events
if(page==0)
page=1;
else page=page+1;
Toast.makeText(Myprofile.this,""+page,Toast.LENGTH_SHORT).show();
@Override
protected String doInBackground(String... params)
// Gets data from api
BufferedReader reader=null;
String cert="id="+id+"&page="+page;
try
url = new URL(URI_URL);
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.connect();
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
wr = new DataOutputStream(conn.getOutputStream());
wr.writeBytes(cert);
wr.flush();
wr.close();
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sBuilder = new StringBuilder();
String line = "";
while ((line = reader.readLine()) != null)
sBuilder.append(line + "\n");
result = sBuilder.toString();
reader.close();
conn.disconnect();
return result;
catch (Exception e)
e.printStackTrace();
System.err.println("cassies"+ result);
return result;
@Override
protected void onPostExecute(String s)
super.onPostExecute(s);
try
// Data is returned in Json Format
JSONObject jsonn= new JSONObject(result);
JSONArray jArray = jsonn.getJSONArray("myprofile");
JSONObject jobject=null;
JSONArray sss= new JSONArray();
for(int i=0; i < jArray.length(); i++)
jobject= jArray.getJSONObject(i);
jobject.getString("post");
jobject.getString("fullname");
sss.put(jobject);
jsonn.put("myprofile", sss);
// Callout BaseAdapter to populate columns
Myprofile_CustomView BA=new Myprofile_CustomView(jsonn,Myprofile.this);
// Set the adapter notice the data comes from BaseAdapter BA
mm.setAdapter(DMF);
catch (Exception e)
pb.setVisibility(View.INVISIBLE);
这是我的更新代码
public class Myprofile extends Activity
String URI_URL;
Integer page;
ProgressBar pb;
ListView mm;
Myprofile_CustomView BA;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.myprofile);
URI_URL = getResources().getString(R.string.PathUrl) + "/api/myprofile";
page=0;
new Myprofile_Async().execute();
// Listview for adapter
mm= (ListView)findViewById(R.id.myprofiles);
mm.setAdapter(BA);
// Listview to use inside scroll event
/*
final ListView lv=(ListView)findViewById(R.id.myprofiles);
lv.setOnScrollListener(new AbsListView.OnScrollListener()
@Override
public void onScrollStateChanged(AbsListView view, int scrollState)
// fires off when scroll close to bottom
if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE && (lv.getLastVisiblePosition() - lv.getHeaderViewsCount() - lv.getFooterViewsCount()) >= (view.getCount() - 1))
new Myprofile_Async().execute();
@Override
public void onScroll(AbsListView absListView, int i, int i1, int i2)
);
*/
public class Myprofile_Async extends AsyncTask<String,String,String>
HttpURLConnection conn;
URL url;
String result="";
DataOutputStream wr;
int id;
@Override
protected void onPreExecute()
super.onPreExecute();
pb=(ProgressBar)findViewById(R.id.progressBar);
pb.setVisibility(View.VISIBLE);
id= getIntent().getExtras().getInt("id");
// page Int is used to keep count of scroll events
if(page==0)
page=1;
else page=page+1;
Toast.makeText(Myprofile.this,""+page,Toast.LENGTH_SHORT).show();
@Override
protected String doInBackground(String... params)
// Gets data from api
BufferedReader reader=null;
String cert="id="+id+"&page="+page;
try
url = new URL(URI_URL);
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.connect();
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
wr = new DataOutputStream(conn.getOutputStream());
wr.writeBytes(cert);
wr.flush();
wr.close();
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sBuilder = new StringBuilder();
String line = "";
while ((line = reader.readLine()) != null)
sBuilder.append(line + "\n");
result = sBuilder.toString();
reader.close();
conn.disconnect();
return result;
catch (Exception e)
e.printStackTrace();
System.err.println("cassies"+ result);
return result;
@Override
protected void onPostExecute(String s)
super.onPostExecute(s);
try
// Data is returned in Json Format
JSONObject jsonn= new JSONObject(result);
JSONArray jArray = jsonn.getJSONArray("myprofile");
JSONObject jobject=null;
JSONArray sss= new JSONArray();
for(int i=0; i < jArray.length(); i++)
jobject= jArray.getJSONObject(i);
jobject.getString("post");
jobject.getString("fullname");
sss.put(jobject);
System.err.println("mpee: "+ sss);
jsonn.put("myprofile", sss);
// Callout BaseAdapter
// Myprofile_CustomView DMF=new Myprofile_CustomView(jsonn,Myprofile.this);
// Set the adapter again
BA.updateResults(jsonn,Myprofile.this);
BA.notifyDataSetChanged();
catch (Exception e)
System.err.println("mpee: " + e.toString());
pb.setVisibility(View.INVISIBLE);
这是我的 BaseAdapter
public class Myprofile_CustomView extends BaseAdapter
JSONObject names;
Context ctx;
LayoutInflater myiflater;
// Have data come in and do a toast to see changes
public Myprofile_CustomView(JSONObject arr, Context c)
notifyDataSetChanged();
ctx = c;
names = arr;
myiflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
public void updateResults(JSONObject results, Context c)
names=results;
ctx=c;
notifyDataSetChanged();
Toast.makeText(c,names+"",Toast.LENGTH_SHORT).show();
@Override
public int getCount()
try
JSONArray jaLocalstreams = names.getJSONArray("myprofile");
return jaLocalstreams.length();
catch (Exception e)
Toast.makeText(ctx, "Error: Please try again", Toast.LENGTH_LONG).show();
return names.length();
@Override
public Object getItem(int position)
return position;
@Override
public long getItemId(int position)
return position;
@Override
public View getView(int position, View convertView, ViewGroup parent)
View row=convertView;
MyViewHolder holder=null;
try
if(row==null)
LayoutInflater li = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = li.inflate(R.layout.zmyprofile,parent,false);
holder=new MyViewHolder(row);
row.setTag(holder);
// Log.d("VIX", "Creating new Row");
else
holder=(MyViewHolder)row.getTag();
// Log.d("VIX", "Recycling");
JSONArray jaLocalstreams = names.getJSONArray("myprofile");
final JSONObject jsonObject = jaLocalstreams.getJSONObject(position);
holder.post.setText(jsonObject.getString("post"));
holder.fullname.setText(jsonObject.getString("fullname"));
return row;
catch (Exception e)
e.printStackTrace();
return row;
class MyViewHolder
TextView post,fullname;
MyViewHolder(View v)
post= (TextView)v.findViewById(R.id.post);
fullname= (TextView)v.findViewById(R.id.fullname);
【问题讨论】:
【参考方案1】:适配器通常需要一个项目列表。
您可以在 onCreate
中定义一个空的项目列表并传递给您的适配器。
现在,当您获得新数据时,只需更新该项目列表,然后调用此函数告诉适配器数据已更改。
yourAdapterObject.notifyDataSetChanged();
【讨论】:
我刚刚做了以下更改,但现在没有任何显示。【参考方案2】:您可以使用notifyDataSetChanged
方法。在您的适配器类中:
private List myList;
...
...
public void update(List newList)
myList = newList;
notifyDataSetChanged();
您第一次定义适配器,在接下来的更新中,您只需使用新列表调用更新方法。
【讨论】:
【参考方案3】:Sharj 是正确的,因为您可以将新数据添加到现有(空)适配器。不需要调用该方法 .notifyDataSetChanged() 因为这是在适配器代码内部调用的。
查看显示内部调用的source for ArrayAdapter。
【讨论】:
哦,好的,我刚刚查看了一下,我有一个正确更新的 ArrayAdapter,但是由于这是另一端的 JsonObject 需要更新,所以它工作不顺利。我已经更新了我的代码并在上面展示了更多内容。以上是关于Android如何在数据进入后设置listview适配器的主要内容,如果未能解决你的问题,请参考以下文章
android listView,list中有多个值,页面显示两个listView,如何让list中的值在页面中循环显示,谢谢大神…