Android:向数据添加新行后,无法在触摸模式下选择我的 ListView 行

发布于 2024-12-11 13:17:05 字数 4699 浏览 0 评论 0 原文

我有一个活动和一个线程。该线程处理数据(稍后数据将从 Internet 活动中获取,目前,它只是每 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();

        }
        }
        }
        }

好的,提前致谢,任何解决方案将不胜感激

I have an Activity and a Thread. The thread handles the data (later that data will be grabbed from Internet activity, for now, it just automatically adds a new row each 10 seconds). The thing is, after a new row being add, I can't touch the items anymore, to regain focus, I must press the up or down arrow on my hardware keyboard, or the menu button.
Of course I first thought to re-set the .setFocusableOnTouchMode to true, but this didn't seem to solve my problem. Or at least, I'm not setting it on the right place. Anyway this is my code:

The Activity:

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

                }
            }
        }

OK now the Thread.

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

        }
        }
        }
        }

Well, thanks on advance, any solution will be appretiated

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风吹过旳痕迹 2024-12-18 13:17:05

您无法从非 UI 线程的线程中直接修改 UI 元素。如果你想从不同的线程修改UI元素,你必须调用函数runOnUiThread。这意味着您必须将对活动的引用传递给其构造函数中的 Refresh 类,以便您可以在线程上执行以下调用:

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

也就是说,如果我是您,我会废弃它并只使用 AsyncTaskLoader 代替。它更容易,并且该类是专门为异步加载列表视图等元素而创建的。现在编写代码的方式不会很好地工作,并且很容易出现各种错误。在 android 中,一般的经验法则是不要使用原始 Thread 类,除非绝对必要。使用 AsyncTaskLoader、AsyncTask 或 IntentService。

最后注意,如果您正在开发低于 10 的 API 级别,您仍然可以通过 android 支持包

You can't directly modify UI elements from a thread that isn't the UI thread. If you want to modify a UI element from a different thread, you have to call the function runOnUiThread. That means you'll have to pass a refernce to the activity to the Refresh class in it's constructor so you can do the following call on your thread:

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

That said, if I were you I'd scrap this and just use an AsyncTaskLoader instead. It's much easier and the class was specifically created for asynchronously loading up elements in things like a listview. The way you have the code written right now is not going to work very well and is prone to all kinds of error. In android, a general rule of thumb is to not use the raw Thread class unless you abosultely have to. Use either the AsyncTaskLoader, AsyncTask, or IntentService.

Final note, if you're developing for API levels less than 10, you can still access the AsyncTaskLoader class via the android Support Package.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文