【问题标题】:How to get live updates via JSON to listview如何通过 JSON 获取实时更新到 listview
【发布时间】:2012-04-17 12:44:24
【问题描述】:

我找不到通过 JSON 获取列表视图的实时更新的方法。

我的活动是从网页请求 JSON 数据,代码是:

public class Second extends Activity {

    static final String Li_nk = "LinkName:";
    static final String Image_name = "ImageName:";
    ListView list;
    public final static String AUTH = "authentication";
    static final String KEY_THUMB_URL = "thumb_image"; // Uri.decode("http://zeesms.info/android_app_images/Koala.jpg");

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Intent i2 = getIntent();
        String wrd = i2.getStringExtra("entrd");
        Log.v("keyis", wrd);

        // if(wrd.equalsIgnoreCase("test")){
        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) {
            alertbox();
            Log.e("loG_tag", "Error parsing" + e.toString());
        }

        list = (ListView) findViewById(R.id.lv1);
        this.list.setEmptyView(findViewById(R.id.empty));
        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                // Toast.makeText(getApplicationContext(),"Click ListItem Number "
                // + position, Toast.LENGTH_LONG).show();
                Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.riffre.com/"));
                startActivity(myIntent);
            }

        });
        LazyAdapter adapter = new LazyAdapter(this, mylist);

        list.setAdapter(adapter);
        list.setItemsCanFocus(false);

        // }
        /*
         * else{ alertbox(); }
         */

    }

    /*
     * public void register(View view) { Log.w("C2DM",
     * "start registration process"); Intent intent = new
     * Intent("com.google.android.c2dm.intent.REGISTER");
     * intent.putExtra("app", PendingIntent.getBroadcast(this, 0, new
     * Intent(), 0)); // Sender currently not used intent.putExtra("sender",
     * "nonsenses@gmail.com"); startService(intent); }
     * 
     * public void showRegistrationId(View view) { SharedPreferences prefs =
     * PreferenceManager .getDefaultSharedPreferences(this); String string =
     * prefs.getString(AUTH, "n/a"); Toast.makeText(this, string,
     * Toast.LENGTH_LONG).show(); Log.d("C2DM RegId", string);
     * 
     * }
     */
    public void alertbox() {

        new AlertDialog.Builder(this).setMessage("Invalid Keyword,No Results found").setTitle("Alert").setCancelable(true).setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface dialog, int whichButton) {

                finish();

            }
        }).show();
    }
}

我正在使用自定义适配器,代码如下:

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

我想要的是应用程序每分钟左右用数据更新列表视图。列表中的最新条目也应位于顶部。

最好的方法是什么?

【问题讨论】:

    标签: android json web-services listview


    【解决方案1】:

    将您的 JSON 解析代码(可能是您的 try..catch 块)放在单独的函数中,而不是放在 onCreate() 中。

    因此可以轻松地每分钟调用该部分。假设函数名称LoadData() 还添加了一行adapter.notifyDataSetChanged() 以每次更新适配器/列表。

    现在在您的 onCreate() 中,编写此代码以每隔一分钟调用一次该函数,

        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, 1000);
            }
        };
        handler.postDelayed(runable, 1000);
    

    现在第二个问题,在顶部添加新数据..

    我现在只想写一个循环,在调用适配器通知更改之前将其添加到您的函数中,例如

         ArrayList<HashMap<String,String>> mylist = new  ArrayList<HashMap<String,String>>(); 
         ArrayList<HashMap<String,String>> mylistTemp = new  ArrayList<HashMap<String,String>>();
         for(int i = mylist.size()-1 ; i >=0;i--)
         {
             mylistTemp.add(mylist.get(i));
         }
         mylist = mylistTemp;
    

    【讨论】:

    • 我已经为第一部分实现了你的代码,现在它不断更新,相同的数据不断添加到列表中,我还添加了 notifydatasetchanged(),这可能是什么原因造成的?
    • 再见same data is being added to the list constantly是什么意思?
    • 列表不断添加相同数据的新视图,就像永无止境的更新
    • 好的,我已经解决了这个问题,虽然每次更新,它都会滚动回第一个位置,无论如何我可以在不使用异步任务的情况下保持滚动位置吗??
    • 是的,每次你 notifyChange 适配器也使用 listView.setSelection(positionToMove)
    【解决方案2】:

    如果您上面的代码可以正常工作,您应该可以通过以下步骤实现您的目标:

    • 将您的 JSON 加载代码提取到 AsyncTask 中,您可以每分钟触发一次。 (AsyncTask)
    • 使用 AsyncTask 更新您的 ListAdapter。

    【讨论】:

    • 那么代码肯定可以工作,而且我是 android 的菜鸟,所以你能提供一个类似于这个实例或类似的例子吗?
    【解决方案3】:

    这是 onCreate() 方法的一个可能实现,它将每分钟运行一次更新任务:

    public class JSON_AndroidActivity extends Activity {
        /** Called when the activity is first created. */
        private JSONLoaderTask mJSONLoaderTask;
        private Handler mHandler;
        private ArrayAdapter<String> mArrayAdapter;
        private Runnable mRefresher = new Runnable() {
    
            @Override
            public void run() {
                mJSONLoaderTask = new JSONLoaderTask(JSON_AndroidActivity.this, mArrayAdapter);
                mJSONLoaderTask.execute("");
                mHandler.postDelayed(this, 1000);
    
            }
        };
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            mHandler.postDelayed(mRefresher, 1000);
        }
    }
    

    这是一个可能任务的外壳实现,您可以在其中执行繁重的负载并更新列表的适配器:

    public class JSONLoaderTask extends AsyncTask<String, String, String> {
        private Context context;
        private ProgressDialog progressDialog;
        private final ArrayAdapter<String> mArrayAdapter;
    
        public JSONLoaderTask(Context pContext, ArrayAdapter<String> pArrayAdapter) {
            this.context = pContext;
            this.mArrayAdapter = pArrayAdapter;
        }
    
        @Override
        protected void onPreExecute() {
            progressDialog = new ProgressDialog(context);
            progressDialog.show();
        }
    
        @Override
        protected String doInBackground(String... params) {
             String result = getJSONStream();
            return result;
        }
    
        private String getJSONStream() {
            //load your string here
            return "";
        }
    
        @Override
        protected void onPostExecute(String result) {
            progressDialog.dismiss();
            // Update your ArrayAdapter
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2017-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-22
      • 1970-01-01
      • 1970-01-01
      • 2018-07-19
      • 2014-05-22
      相关资源
      最近更新 更多