ListView项目焦点行为

时间:2012-01-23 19:29:44

标签: android android-listview

我正在尝试创建一个ListView(包含自定义CursorAdapterEditText个项目,以使EditTexts首先显示为不可编辑,并在长时间点击后变为可编辑状态。然后,用户将编辑EditText内容,EditText将在失去焦点时保存对db的更改。然而,我遇到了一个非常讨厌的行为,阻止我这样做。

1)我已将EditTexts设置为android:focusable="false"android:focusableInTouchMode="false"的XML格式。

2)我在OnItemLongClickListener中创建了ListActivity,执行以下操作:

public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id)
{
    Log.d("NLAc", "longClick called");
    EditText et = (EditText) view.findViewById(R.id.etFolderName);
    et.setFocusable(true);
    et.setFocusableInTouchMode(true);
    return true;
}

3)当我在我的适配器中创建视图时,我附加了以下焦点更改侦听器:

public void onFocusChange(View v, boolean hasFocus) 
{
    if (hasFocus)
{
    EditText et = (EditText)v;
    Log.d(TAG, "hasFocus true called " + et.getText());
    et.setText("focused");
    et.setSelection(et.length());
}
else
{
    EditText et = (EditText)v;
    Log.d(TAG, "hasFocus false called " + et.getText());
    et.setText("unfocused");
    et.setFocusableInTouchMode(false);
            //TODO Save to DB
}

}

当我长时间点击第一个项目时,我会在日志中获得以下内容:

longClick called

hasFocus true called item1

hasFocus false called focused

如果我将焦点线设置删除为false(et.setFocusableInTouchMode(false);),我会得到另一个hasFocus true called unfocused。 事情显然是这样的:

1)EditText在设定焦点时获得焦点

2)LinearLayour包含我的ListView失去焦点并在其所有孩子身上调用内部unFocus(),包括我的EditText

3)EditText失去焦点

4)EditText成为焦点 - 无论出于何种原因。

此行为可以防止我在失去焦点或使其无法对焦时禁用EditText,直到下一次长按才能通过,这就是我想要的。 任何人都可以建议我可能会缺少什么?或解释一下这种行为?任何解决方案都表示赞赏。

2 个答案:

答案 0 :(得分:2)

通过在彼此之上使用两个视图,我能够取得一些进展。我正在使用TextView进行无焦点显示,我隐藏它并在长按时显示EditText。但是,在我尝试为ViewGroups定义的android:descendantFocusability设置之前,这对于ListView真正奇怪的焦点处理起初并没有真正帮助。在我将它设置为ViewGroup.FOCUS_AFTER_DESCENDANTS后,它的行为变得更加可预测,至少对我而言。

答案 1 :(得分:1)

行。这是你的代码。希望它符合您的需求,或者至少是我从您的帖子中得到的:)


import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.text.InputFilter;
import android.text.Spanned;
import android.util.Log;
import android.view.*;
import android.widget.*;
import java.util.ArrayList;
import java.util.List;

public class EditListActivity extends Activity {


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LinearLayout ll = new LinearLayout(this);
        LinearLayout.LayoutParams lp1 = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.WRAP_CONTENT,
                LinearLayout.LayoutParams.WRAP_CONTENT);
        ll.setLayoutParams(lp1);
        ll.setOrientation(1);
        ListView lv = new ListView(this);
        MyListAdapter adapter = new MyListAdapter(this, null);
        lv.setAdapter(adapter);
        ll.addView(lv);
        setContentView(ll);

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }


    class MyListAdapter extends BaseAdapter implements View.OnLongClickListener, View.OnFocusChangeListener {
        private final String TAG = ListActivity.class.getName();
        List<String> stringsarray;
       private Context context;

        public MyListAdapter(Context context, List<String> phonebook) {
            this.stringsarray = new ArrayList<String>();

            this.stringsarray.add("test1");
            this.stringsarray.add("test2");
            this.stringsarray.add("test3");
            Log.d(TAG, "created list adapter");
            this.setContext(context);
        }

        public int getCount() {
            return this.stringsarray.size();
        }

        public String getItem(int position) {
            return this.stringsarray.get(position);
        }

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


        public View getView(final int position, View convertView, ViewGroup parent) {
            LinearLayout rl = new LinearLayout(getContext());

            rl.setOrientation(1);
            EditText text = new EditText(getContext());

            text.setOnLongClickListener(this);
            text.setOnFocusChangeListener(this);
            text.setText(this.stringsarray.get(position));

            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.FILL_PARENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);

            text.setFocusable(true);
            rl.addView(text, lp);
            return rl;
        }

        public void onFocusChange(View view, boolean b) {
            EditText et = (EditText) view;
                et.setFilters(new InputFilter[]{
                        new InputFilter() {
                            public CharSequence filter(CharSequence src, int start,
                                                       int end, Spanned dst, int dstart, int dend) {
                                return src.length() < 1 ? dst.subSequence(dstart, dend) : "";
                            }
                        }
                });
            if (b) {
                Log.d(TAG, "hasFocus true called " + et.getText());
                et.setText("focused");
                et.setSelection(et.length());

            } else {

                Log.d(TAG, "hasFocus false called " + et.getText());
                et.setText("unfocused");
                //TODO Save to DB
            }
        }

        public boolean onLongClick(View view) {
            getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
            final EditText et = (EditText) view;
            et.setFilters(new InputFilter[]{
                        new InputFilter() {
                            public CharSequence filter(CharSequence src, int start,
                                                       int end, Spanned dst, int dstart, int dend) {
                               return src;
                            }
                        }
                });
            et.setText("editable");
            Log.d(TAG, "on long click called " + et.getText());
            et.requestFocus();
            et.setFocusableInTouchMode(true);

            return true;
        }

        public Context getContext() {
            return context;
        }

        public void setContext(Context context) {
            this.context = context;
        }
    }

}

玩得开心。