【问题标题】:Android how can i set listview adapter when data comes in after itAndroid如何在数据进入后设置listview适配器
【发布时间】: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);

        }

    }


}

【问题讨论】:

    标签: android android-listview android-asynctask baseadapter


    【解决方案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 需要更新,所以它工作不顺利。我已经更新了我的代码并在上面展示了更多内容。
      猜你喜欢
      • 2016-06-22
      • 1970-01-01
      • 2015-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多