NullpointerException при обновлении пользовательского интерфейса

Я читаю некоторые записи из базы данных и загружаю их в ListView. ListView состоит из CheckBox и TextView. Загрузка осуществляется более 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);
            }
        }   
    }

Этот код выше работает только тогда, когда список заполнен элементами, и если этот код находится в OnClickListener(), но он не работает, если я запускаю его из onPostExecute, потому что кажется, что все строки в списке не загружены. Итак, мой вопрос: что мне делать, чтобы получить информацию, когда загрузка всех строк завершена, и после этого проверить, какие элементы следует проверять в соответствии с данными, которые я получаю из базы данных?


person Josef    schedule 25.07.2013    source источник
comment
Хорошо покажите нам код, где вы инициализируете listView   -  person NitroG42    schedule 25.07.2013
comment
вы не должны использовать свой список таким образом. используйте выбранный listadapter для поддержки ваших данных db (например, адаптера курсора) и флага/снятия флага/setText и т. д. на основе этого внутри ваших адаптеров getView   -  person Christian R.    schedule 25.07.2013


Ответы (3)


Из-за повторного использования представления listView.getChildAt() будет возвращать представление только для тех позиций, которые оно отображает, а не для нескольких.

вы можете проверить этот другой вопрос здесь. у него есть ответ, который вы ищете: ListView getChildAt возвращает значение null для видимых детей

person bofredo    schedule 25.07.2013

В вашем случае я думаю, что этот фрагмент кода должен быть внутри реализации вашего адаптера getView.

Здесь вы идете с примерами на

И как использовать их с вашим списком.

person jfs    schedule 25.07.2013
comment
здесь есть пример использования SimpleCursorAdapter и CustomCursorAdapter - стесняться редактировать его прямо в ответе jfs: -о - person Christian R.; 25.07.2013

Прежде всего, вы знаете, когда список загружается, читая количество элементов в вашем наборе данных, и если набор данных списка равен этому, то все данные загружаются в список. К сожалению, я больше не могу вам помочь с этим, поскольку я не вижу здесь ваш код загрузки данных..

Во-вторых, вы должны изменить:

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

            }

В пользовательском адаптере. Здесь приведен пример пользовательского адаптера, а также шаблон ViewHolder.

person Cata    schedule 25.07.2013