【问题标题】:Nullpointerexception while updating UI更新 UI 时出现 Nullpointerexception
【发布时间】:2013-08-20 19:15:13
【问题描述】:

我正在从数据库中读取一些记录并将它们加载到ListViewListViewCheckBoxTextView 组成。加载通过AsyncTask 完成。这部分应用程序运行良好。

下一步是根据数据库中的一些标志自动检查一些复选框,这里我遇到了问题。我正在尝试检查onPostExecute() 中的那些项目,然后我收到关于NullPointerException 的错误。例如,如果我从按钮小部件的setOnClickListener() 执行相同操作,则它可以正常工作。

问题是如何检查ListView 是否已填充,复选框和TextView 是否已加载并在屏幕上可见?

我不知道它是否会帮助程序中断的代码部分看起来像:

        for (j=0; j<3; j++)
    {
        LinearLayout itemLayout = (LinearLayout)listView.getChildAt(j); // Find by under LinearLayout
        CheckBox checkbox = (CheckBox)itemLayout.findViewById(R.id.ColChk);

        for (k=0; k<rbmjere.size(); k++)
        {
            if (checkbox.getTag().toString() == rbmjere.get(k).toString())
            {
                checkbox.setChecked(true);

            }
        }   
    }

它在那一行中断:

LinearLayout itemLayout = (LinearLayout)listView.getChildAt(j);

我必须提到,这仅在我手动按下运行代码以自动检查框的按钮时才有效,并且仅在加载所有数据时才有效。


这是我的代码:

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_spckontrola_update);

    listView = (ListView)findViewById(R.id.listView1);

    btnPohrani = (Button)findViewById(R.id.btnPohrani);

    btnProvjeri = (Button)findViewById(R.id.btnProvjeri);

    btnProvjeri.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

            new loadSPCKontrole().execute("FCN");
        }
    });
MyArrList = new ArrayList<HashMap<String, String>>();

public void fillData()
{                       
    SimpleAdapter listadapter = new SimpleAdapter(this, MyArrList, R.layout.activity_list_row,

    new String[] {"OpisMjere", "RbMjere"}, new int[] {R.id.ColOpis, R.id.ColCode});

    listView = (ListView)findViewById(R.id.listView1);
    listView.setAdapter(listadapter);       
}

private class loadSPCKontrole extends AsyncTask<String, Void, Void>
{                   

    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(SPCUpdate.this);
        pDialog.setMessage("Loading in progress ...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(false);
        pDialog.show();
    }

    @Override
    protected Void doInBackground(String... params) {

        HashMap<String, String> map;

        String k = params[0].toString();
        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        nameValuePairs.add(new BasicNameValuePair("sIDKategorija", k));

        try
        {                       
                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost("http://192.168.16.48" + "/spc/get_spcmjere.php");
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                HttpResponse response = httpclient.execute(httppost);
                HttpEntity entity = response.getEntity();
                is = entity.getContent();
        }
        catch(Exception e)
        {
                 Log.e("log_tag", "Error in http connection "+ e.toString());
        }

        try
        {
               BufferedReader reader = new BufferedReader(new InputStreamReader(is,"UTF-8"),8);
               sb = new StringBuilder();
               sb.append(reader.readLine() + "\n");

               String line="0";
               while ((line = reader.readLine()) != null) {
                              sb.append(line + "\n");
                }
                is.close();
                result=sb.toString();

        }
        catch(Exception e)
        {
            Log.e("log_tag", "Error converting result " + e.toString());
        }

        int ct_id;
        String ct_name;

        try
        {

              jArray = new JSONArray(result);
              JSONObject json_data=null;
              for(int i=0;i<jArray.length();i++){
                     json_data = jArray.getJSONObject(i);
                     ct_id=json_data.getInt("RbMjere");
                     ct_name=json_data.getString("OpisMjere");

                     map = new HashMap<String, String>();
                     map.put("RbMjere", String.valueOf(ct_id));
                     map.put("OpisMjere", ct_name);

                     MyArrList.add(map);
                 }                    

         }
        catch(JSONException e1)
        {
            Log.e("Greška konvertiranja", e1.toString());
        } 
        catch (ParseException e1) 
        {
            e1.printStackTrace();
        }

        return null;
    }

    protected void onPostExecute(Void result)
    {
        super.onPostExecute(result);

        fillData();

        listView.setAdapter(new SPCMjereAdapter(SPCUpdate.this));

        pDialog.dismiss();

    }
}

   public class SPCMjereAdapter extends BaseAdapter 
    {
        private Context context;

        public SPCMjereAdapter(Context c) 
        {           
            context = c;                    
        }

        public int getCount() {
            return MyArrList.size();
        }

        public Object getItem(int position) {
            return position;
        }

        public long getItemId(int position) {
            return position;
        }

        public View getView(final int position, View convertView, ViewGroup parent) {

            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            if (convertView == null) {
                convertView = inflater.inflate(R.layout.activity_list_row, null); 

            }

            // ColID
            TextView txtOpis = (TextView) convertView.findViewById(R.id.ColOpis); 
            txtOpis.setText(MyArrList.get(position).get("OpisMjere") +".");

            // ColCode
            TextView txtRbMjere = (TextView) convertView.findViewById(R.id.ColCode);
            txtRbMjere.setText(MyArrList.get(position).get("RbMjere"));


            // ColChk               
            CheckBox Chk = (CheckBox) convertView.findViewById(R.id.ColChk);
            Chk.setTag(MyArrList.get(position).get("RbMjere"));

            return convertView;

        }

    }

这是我如何获取应检查的项目的代码:

DB objDB = new DB();
    ArrayList<Integer> rbmjere = objDB.getCheckedSPC(ID);

    int k=0;
    int j=0;
    for (j=0; j<MyArrList.size(); j++)
    {

        LinearLayout itemLayout = (LinearLayout)listView.getChildAt(j); // Find by under LinearLayout
        CheckBox checkbox = (CheckBox)itemLayout.findViewById(R.id.ColChk);

        for (k=0; k<rbmjere.size(); k++)
        {
            if (checkbox.getTag().toString() == rbmjere.get(k).toString())
            {
                checkbox.setChecked(true);
            }
        }   
    }

上面的代码仅在 listview 填充了项目并且此代码位于 OnClickListener() 下时才有效,但如果我从 onPostExecute 运行它则不起作用,因为似乎未加载 listview 中的所有行。所以我的问题是,当所有行的加载完成时,我应该怎么做才能获取信息,然后根据我从数据库中获得的数据检查哪些项目应该被检查?

【问题讨论】:

  • 向我们展示你初始化listView的代码
  • 你不应该那样使用你的列表视图。使用选择的 listadapter 来维护您的 db 数据(例如光标适配器)和 flag/unflag/setText 等,基于您的适配器 getView

标签: android android-asynctask android-checkbox


【解决方案1】:

由于视图回收,listView.getChildAt() 将只返回它正在显示的位置的视图,而不是多个。

您可以在此处查看其他问题。它有您正在寻找的答案: ListView getChildAt returning null for visible children

【讨论】:

    【解决方案2】:

    在你的情况下,我认为那段代码应该在你的适配器的 getView 实现中。

    这里有例子

    以及如何将它们与您的列表一起使用。

    【讨论】:

    【解决方案3】:

    首先,您可以通过读取数据集中的项目数知道何时加载列表,如果列表视图的数据集等于该数据集,则所有数据都加载到列表视图中。不幸的是,我不能为您提供更多帮助,因为我在这里看不到您的数据加载代码..

    其次,你应该改变:

    for (j=0; j<3; j++)
    

    int listChildSize = listView.getChildCount();
    for (j = 0; j < listChildSize ; j++)
    

    编辑

    jfs 是对的,你应该添加:

    if (checkbox.getTag().toString() == rbmjere.get(k).toString())
                {
                    checkbox.setChecked(true);
    
                }
    

    在自定义适配器中。 Here 是自定义适配器的示例,也是 ViewHolder 模式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多