我已经阅读了很多示例,但是如果我希望在ListView
更新JSON
之后保持我的滚动位置,那么我可以在不使用AsyncTask
实例的情况下执行此操作吗? ??
我的列表代码是
String wrd;
//ArrayList<HashMap<String,String>> mylist;
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent i2=getIntent();
wrd=i2.getStringExtra("entrd");
Log.v("keyis",wrd);
final Handler handler = new Handler();
Runnable runable = new Runnable() {
@Override
public void run() {
//call the function
LoadData();
//also call the same runnable
handler.postDelayed(this, 40000);
}
};
handler.postDelayed(runable, 10);
}public void LoadData(){
JSONObject j2=JSONfunctions.getJSONfromURL("/webservice_search.php?keyword="+wrd+"&format=json");
ArrayList<HashMap<String,String>> mylist = new ArrayList<HashMap<String,String>>();
try{JSONArray jray=j2.getJSONArray("listings");
for(int i=0;i<jray.length();i++){
Log.v("state","json data being read");
JSONObject j3= jray.getJSONObject(i);
String first=j3.getString("listing");
Log.v("sublist", first);
JSONObject j4=j3.getJSONObject("listing");
String sec=j4.getString("links");
int maxLength = (sec.length() < 30)?sec.length():27;
sec.substring(0, maxLength);
String cutsec=sec.substring(0,maxLength);
Log.v("links are",cutsec);
String img=j4.getString("image_name");
Log.v("image name is ",img);
//Uri dimg=Uri.parse("http://zeesms.info/android_app_images/Koala.jpg");
HashMap<String,String> map=new HashMap<String,String>();
map.put("Id",String.valueOf(i));
map.put(Li_nk,cutsec);
map.put(Image_name,j4.getString("image_name"));
map.put(KEY_THUMB_URL,"http://zeesms.info/android_app_images/"+img);
mylist.add(map);
}
}
catch(JSONException e){
Log.e("loG_tag","Error parsing"+e.toString());
}
LazyAdapter adapter = new LazyAdapter(this,mylist);
adapter.notifyDataSetChanged();
ListView list=(ListView)findViewById(R.id.lv1);
list.setEmptyView(findViewById(R.id.empty));
list.setAdapter(adapter);
list.setItemsCanFocus(false);
,我的适配器
public class LazyAdapter extends BaseAdapter {
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater=null;
public ImageLoader imageLoader;
public LazyAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader=new ImageLoader(activity.getApplicationContext());
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return data.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.custom_row_view1, null);
TextView title = (TextView)vi.findViewById(R.id.linkname); // merchnts name
TextView artist = (TextView)vi.findViewById(R.id.imagename); // address
//TextView duration = (TextView)vi.findViewById(R.id); // distance
ImageView thumb_image=(ImageView)vi.findViewById(R.id.mClogo); // logo
HashMap<String, String> jsn = new HashMap<String, String>();
jsn = data.get(position);
// Setting all values in listview
title.setText(jsn.get(Second.Li_nk));
artist.setText(jsn.get(Second.Image_name));
//duration.setText(song.get(CustomizedListView.KEY_DURATION));
imageLoader.DisplayImage(jsn.get(Second.KEY_THUMB_URL), thumb_image);
return vi;
}
最后用于json解析的类是
public class JSONfunctions {
public static JSONObject getJSONfromURL(String url){
InputStream is = null;
String result = "";
JSONObject jArray = null;
String str1="http://zeesms.info"+url;
// ArrayList<NameValuePair> namevaluepairs = new ArrayList<NameValuePair>();
Log.v("url result",url);
//namevaluepairs.add(new BasicNameValuePair("location",str1));
//http post
try{
HttpClient httpclient= new DefaultHttpClient();
HttpGet request = new HttpGet();
request.setURI(new URI(str1));
HttpResponse response = httpclient.execute(request);
is = response.getEntity().getContent();
if(is==null){
Log.v("url result","is null");
}
else
{
Log.v("url result","is not null");
}
/* BufferedReader buf = new BufferedReader(new InputStreamReader(is,"UTF-8"));
StringBuilder sb = new StringBuilder();
String s;
while(true )
{
s = buf.readLine();
if(s==null || s.length()==0)
break;
sb.append(s);
}
buf.close();
is.close();
sb.toString(); */
// httppost.setEntity(new UrlEncodedFormEntity(namevaluepairs));
//HttpResponse response=httpclient.execute(httppost);
//HttpEntity entity=response.getEntity();
//is=entity.getContent();
/*
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
*/
}catch(Exception e){
Log.v("log_tag", "Error in http connection "+e.toString());
AlertDialog.Builder alert=new AlertDialog.Builder(null);
alert.setMessage("Invalid Keyword").setPositiveButton("Ok", new OnClickListener(){
@Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
}
});
}
//convert response to string
try{
Log.v("url result","getting result starts");
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
StringBuilder sb = new StringBuilder();
String line = null;
Log.v("url result","getting result");
while ((line = reader.readLine()) != null) {
Log.v("url result","getting result");
sb.append(line + "\n");
}
is.close();
result=sb.toString();
Log.v("url result",result);
}catch(Exception e){
Log.e("log_tag", "Error converting result "+e.toString());
}
try{
jArray = new JSONObject(result);
}catch(JSONException e){
Log.e("log_tag", "Error parsing data "+e.toString());
}
return jArray;
}
}
如果数据是从网页更新的话,那么在最上面显示更新项目的最简单方法是什么?
答案 0 :(得分:27)
仅通过调用notifydatasetchanged()来维护滚动位置更容易。问题在于,每次数据更新时都要创建一个新的适配器......你应该这样做:
if(listView.getAdapter()==null)
listView.setAdapter(myAdapter);
else{
myAdapter.updateData(myNewData); //update adapter's data
myAdapter.notifyDataSetChanged(); //notifies any View reflecting data to refresh
}
这样,您的列表视图将保留滚动位置。
如果您想要滚动到新位置,请使用:
list.smoothScrollToPosition(int position);
答案 1 :(得分:7)
如果由于某种原因您不想调用notifyDataSetChanged(),您可以使用setSelectionFromTop()
来维护位置在更新适配器之前:
lastViewedPosition = listView.getFirstVisiblePosition();
//get offset of first visible view
View v = listView.getChildAt(0);
topOffset = (v == null) ? 0 : v.getTop();
更新适配器后:
listView.setSelectionFromTop(lastViewedPosition, topOffset);
答案 2 :(得分:6)
list.smoothScrollToPosition(int position); //my favorite :)
它也可以帮助您滚动不错的特定项目
答案 3 :(得分:5)
listview.setSelection( i );
这将帮助您在顶部设置特定行
答案 4 :(得分:2)
总体情况:
在您的API响应回调中,请调用以下函数(示例):
int ISBN, r, i;
String st;
Scanner keyboard;
keyboard = new Scanner(System.in);
System.out.println("Please enter the first 9 digits of your ISBN number:");
ISBN = keyboard.nextInt();
st = ("" + ISBN);
if (st.length() == 9){
r = (st.charAt(0) * 1 + st.charAt(1) * 2 + st.charAt(2) * 3 + st.charAt(3) * 4 + st.charAt(4) * 5 + st.charAt(5) * 6 + st.charAt(6) * 7 + st.charAt(7) * 8 + st.charAt(8) * 9);
if (r % 11 == 10){
System.out.println("Your ISBN Number is: " + ISBN + "X");
}
else {
System.out.println(st);
i = (ISBN * 10) + (r % 11);
System.out.println("Your ISBN Number is: " + i);
}
}
else {
System.out.println("This is an invalid ISBN entry!");
}
答案 5 :(得分:1)
如果您正在使用ArrayAdapter(或其子类),则问题可能是由于适配器在添加新项目之前清理它时更新了列表:
adapter.clear();
adapter.addAll(...);
您可以通过包装修改适配器的代码来修复它:
adapter.setNotifyOnChange(false); // Disable calling notifyDatasetChanged() on modification
adapter.clear();
adapter.addAll(...); // Notify the adapter about that data has changed. Note: it will re-enable notifyOnChange
adapter.notifyDataSetChanged();