Android: Мои строки ListView не могут быть выбраны в сенсорном режиме после добавления новой строки в данные - PullRequest
0 голосов
/ 25 октября 2011

У меня есть активность и тема.Поток обрабатывает данные (позже эти данные будут извлечены из интернет-активности, сейчас он просто автоматически добавляет новую строку каждые 10 секунд).Дело в том, что после добавления новой строки я больше не могу касаться элементов, чтобы восстановить фокус, я должен нажать стрелку вверх или вниз на своей аппаратной клавиатуре или кнопку меню.Конечно, я сначала подумал, чтобы переустановить .setFocusableOnTouchMode в true, но это, похоже, не решило мою проблему.Или, по крайней мере, я не устанавливаю это в правильном месте.В любом случае это мой код:

Активность:

    $
    package com.ejemplolisbox;



import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class EL extends Activity {
    /**
     * @see android.app.Activity#onCreate(Bundle)
     */





    public Refresh actualizar;
        // The thread
    public static ListView g;
    public static EfficientAdapter instance ;
        // The adapter (is a custom made adapter, I didn't do it myself, just grabbed it from the Internet)

        public static String[] abbreviations = {  "Item0",
                "Item1", "Item2"};







            /** Called when the activity is first created. */

            public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.main);
                g = (ListView) findViewById(R.id.lv_country);
                g.setFocusable(true);
                g.setFocusableInTouchMode(true);
                instance = new EfficientAdapter(this);
                                // The adapter is now set to this instance
                g.setAdapter(instance);
                actualizar = new Refresh();
                actualizar.start();
                                //I start the thread

                g.setOnFocusChangeListener(new OnFocusChangeListener() {

                    public void onFocusChange(View arg0, boolean arg1) {
                        // TODO Auto-generated method stub
                        // Code should be here (??)
                    }

                });
                g.setOnItemClickListener(new AdapterView.OnItemClickListener() {

                    public void onItemClick(AdapterView a, View v, int position,
                long id) {

                //use position to get clicked position
                //your code goes here

                }
                });
            }
            public static class EfficientAdapter extends BaseAdapter {
                private LayoutInflater mInflater;

                public EfficientAdapter(Context context) {
                    mInflater = LayoutInflater.from(context);


                }

                public int getCount() {
                    return abbreviations.length;
                }

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

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

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

                    ViewHolder holder;
                    if (convertView == null) {
                        convertView = mInflater.inflate(R.layout.rowlayout, null);
                        holder = new ViewHolder();
                        holder.text1 = (TextView) convertView
                                .findViewById(R.id.TextView01);


                        convertView.setTag(holder);
                    } else {
                        holder = (ViewHolder) convertView.getTag();
                    }

                    holder.text1.setText(abbreviations[position]);



                    return convertView;

                }

                static class ViewHolder {
                    TextView text1;

                }
            }
        }

ОК, теперь тема.

 package com.ejemplolisbox;
     public class Refresh extends Thread{
     public void run(){
    while(true){
    String[] ex=EL.abbreviations;
    String[] ne=new String[ex.length+1];
    for(int i=0;i<ex.length;i++){
        ne[i]=ex[i];
    }
    ne[ex.length]="newItem"+ex.length;
    EL.abbreviations=ne;
    try{
    EL.instance.notifyDataSetChanged();
    EL.g.setFocusableInTouchMode(true);


    }
    catch(Exception e){
        int i = 0;
        EL.g.setFocusableInTouchMode(true);
    }
    EL.g.setFocusableInTouchMode(true);
    try {
        Thread.sleep(10000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();

        }
        }
        }
        }

Что ж, заранее спасибо, любое решение будет оценено

1 Ответ

0 голосов
/ 25 октября 2011

Вы не можете напрямую изменять элементы пользовательского интерфейса из потока, который не является потоком пользовательского интерфейса.Если вы хотите изменить элемент пользовательского интерфейса из другого потока, вам нужно вызвать функцию runOnUiThread .Это означает, что вам нужно передать ссылку на действие классу Refresh в его конструкторе, чтобы вы могли выполнить следующий вызов в вашем потоке:

activity.runOnUiThread(new Runnable(){
  public void run(){
    EL.g.setFocusableInTouchMode(true);
  }
});

Если бы вы были на вашем месте, я быудалите это и просто используйте AsyncTaskLoader вместо этого.Это намного проще, и класс был специально создан для асинхронной загрузки элементов в такие вещи, как просмотр списка.То, как вы пишете код прямо сейчас, не будет работать очень хорошо и подвержено всевозможным ошибкам.В android общее эмпирическое правило состоит в том, чтобы не использовать необработанный класс Thread, если только вам это не нужно.Используйте AsyncTaskLoader, AsyncTask или IntentService.

Заключительное примечание. Если вы разрабатываете для уровней API менее 10, вы все равно можете получить доступ к классу AsyncTaskLoader через android Пакет поддержки .

...