Listview android中的Edittext

Edittext in Listview android

我有Listview与editext和textview。

当我触摸edittext时,edittext失去焦点!

我通过设置android:windowSoftInputMode="adjustPan"(AndroidManifest.xml)解决了这个问题。
现在我触摸edittext而不是editext获得焦点但是应用程序标签和listview的一些原始消失(顶部)。

当用户触摸edittext而不丢失应用程序标签和一些原始列表视图时,我想获得焦点。

我已实施的代码:

当用户触摸edittext时,下面的编码会得到关注,但当软键盘弹出时,应用程序标签和listview的一些原始消失。我希望在用户触摸edittext时获得焦点而不会丢失应用程序标签和一些原始列表视图。

1)的AndroidManifest.xml

1
2
3
4
5
6
7
8
9
10
11
        <activity android:name=".MyListViewDemoActivity"
                  android:label="@string/app_name"
                  android:windowSoftInputMode="adjustPan"
                  >
            <intent-filter>
               
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

</application>

2)raw_layout.xml

1
2
3
4
5
6
7
8
9
10
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <EditText android:id="@+id/mEditText"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  />  
</LinearLayout>

3)main.xml

1
2
3
4
5
6
7
8
9
10
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<ListView android:id="@+id/mListView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>

4)MyListViewDemoActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
public class MyListViewDemoActivity extends Activity {
    private ListView mListView;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mListView=(ListView)findViewById(R.id.mListView);
        mListView.setAdapter(new MyAdapter(this));
    }
}

class MyAdapter extends BaseAdapter {

    private Activity mContext;
    private String character[]={"a","b","c","d","e","f","g","h","i","j"};
    public MyAdapter(Activity context)
    {
        mContext=context;
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return character.length;
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return 0;
    }
private class Holder
{
    EditText mEditText;
}
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        final Holder holder;
        if (convertView == null) {
            holder = new Holder();
            LayoutInflater inflater =mContext.getLayoutInflater();
            convertView = inflater.inflate(R.layout.raw_layout, null);
            holder.mEditText = (EditText) convertView
                    .findViewById(R.id.mEditText);
            convertView.setTag(holder);
        } else {
            holder = (Holder) convertView.getTag();
        }
        holder.mEditText.setText(character[position]);
        holder.mEditText.setOnFocusChangeListener(new OnFocusChangeListener() {

            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                // TODO Auto-generated method stub
                if (!hasFocus){
                    final EditText etxt = (EditText) v;
                    holder.mEditText.setText(etxt.getText().toString());
                }

            }
        });
        return convertView;
    }

}


我遇到了同样的问题。我的数字键盘会在被qwerty键盘和EditText失去焦点取代之前暂时出现。

问题是出现的键盘会使您的EditText失去焦点。为防止这种情况,请在AndroidManifest.xml中为适当的Activity(或Activities)添加以下内容:

1
android:windowSoftInputMode="adjustPan"

请参阅Android文档:

When the input method appears on the screen, it reduces the amount of space available for your app's UI. The system makes a decision as to how it should adjust the visible portion of your UI, but it might not get it right. To ensure the best behavior for your app, you should specify how you'd like the system to display your UI in the remaining space.

To declare your preferred treatment in an activity, use the android:windowSoftInputMode attribute in your manifest's element with one of the"adjust" values.

For example, to ensure that the system resizes your layout to the available space—which ensures that all of your layout content is accessible (even though it probably requires scrolling)—use "adjustResize"


如果没有看到您的代码,我们如何为您的问题建议可能的解决方案。因此,当您提出任何问题时,请继续练习发布可能的代码。

但是,在这里我找到了一个在ListView中实现Android Focusable EditText的教程。完成示例并尝试以您的方式实施或找出问题的解决方案。


我最近解决了"将EditText放在ListView中作为项目"的问题。我不是很擅长英语。所以如果有什么我不清楚解释请告诉我。

我们知道ListView可以垂直滚动,我们希望将EditText作为项目放在ListView中。

第一:

android:windowSoftInputMode="adjustResize"

在活动节点的AndroidManifest.xml中。

第二:
我们创建一个pojo作为模型数据源来控制EditText状态

Line.java

1
2
3
4
5
6
7
public class Line{
    int num;
    String text;
    boolean focus;

    get set method and so on...
}

第三:
我们编写了一个适配器来使EditText适应ListView。

item item_line.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/frameLayout"
    android:layout_width="match_parent"
    android:layout_height="80dp">

    <EditText
        android:id="@+id/etLine"
        android:focusable="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"/>
</FrameLayout>

适配器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
@Override
public View getView(final int position, View convertView, final ViewGroup parent) {
    final ViewHolder holder;
    if (convertView == null) {
        holder = new ViewHolder();
        convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_line, parent, false);
        holder.etLine = (EditText) convertView.findViewById(R.id.etLine);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    final Line line = lines.get(position);

    // step 1: remove android.text.TextWatcher added in step 5 to make sure android.text.TextWatcher
    //         don't trigger in step 2;
    // why?
    //
    // note: When an object of a type is attached to an Editable,
    //       TextWatcher's methods will be called when the EidtText's text is changed.
    //      
    //       EditText use a ArrayList<TextWatcher> type object to store the listener, so we must
    //       make sure there's only one TextWatcher object in this list;
    //
    // Avoid triggering TextWatcher's method in step 2 we remove it at first time.
    //
    if (holder.etLine.getTag() instanceof TextWatcher) {
        holder.etLine.removeTextChangedListener((TextWatcher) (holder.etLine.getTag()));
    }

    // step 2: set text and focus after remove android.text.TextWatcher(step 1);
    holder.etLine.setHint(position +".");

    // set text
    if (TextUtils.isEmpty(line.getText())) {
        holder.etLine.setTextKeepState("");
    } else {
        holder.etLine.setTextKeepState(line.getText());
    }

    // set focus status
    // why?
    //
    // note: ListView has a very elegant recycle algorithm. So views in ListView is not reliable.
    //       Especially in this case, EditText is an item of ListView. Software input window may cause
    //       ListView relayout leading adapter's getView() invoke many times.
    //       Above all if we change EditText's focus state directly in EditText level(not in Adapter).
    //       The focus state may be messed up when the particularly view reused in other position.
    //      
    //       So using data source control View's state is the core to deal with this problem.  
    if (line.isFocus()) {
        holder.etLine.requestFocus();
    } else {
        holder.etLine.clearFocus();
    }

    // step 3: set an OnTouchListener to EditText to update focus status indicator in data source
    // why?
    //
    // in step 2, we know we must control view state through data source. We use OnTouchListener
    // to watch the state change and update the data source when user move up fingers(ACTION_UP).
    // We don't want to consume the touch event, simply return false in method onTouch().
    holder.etLine.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_UP) {
                check(position);
            }
            return false;
        }
    });

    // step 4: set TextWatcher to EditText to listen text changes in EditText to updating the text in data source
    // why?
    //
    // again, use data source to control view state.
    // When user edit the text in one EditText item and scroll the ListView. The particularly EditText item will be
    // reuse in adapter's getView(), this may lead text messed up in ListView.
    // How to deal with this problem?
    // Easy! We update the text in data source at the same time when user is editing. TextWatcher is the best way to
    // do this.
    final TextWatcher watcher = new SimpeTextWather() {

        @Override
        public void afterTextChanged(Editable s) {
            if (TextUtils.isEmpty(s)) {
                line.setText(null);
            } else {
                line.setText(String.valueOf(s));
            }
        }
    };
    holder.etLine.addTextChangedListener(watcher);

    // step 5: Set watcher as a tag of EditText.
    // so we can remove the same object which was setted to EditText in step 4;
    // Make sure only one callback is attached to EditText
    holder.etLine.setTag(watcher);

    return convertView;
}

/**
 * change focus status in data source
 */
private void check(int position) {
    for (Line l : lines) {
        l.setFocus(false);
    }
    lines.get(position).setFocus(true);
}

static class ViewHolder {
    EditText etLine;
}

全部完成!

您可以在我的github中阅读更多详细信息。

演示:https://github.com/Aspsine/EditTextInListView


ListView重新创建视图,
尝试在ScrollView中使用LinearLayout,然后在你的代码中使用runOnUiThread来填充你在另一个线程中的视图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public void fillDataTask(Context context, final LinearLayout listView) {

        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {

                fillView(context, listView);
            }
        });
    }



    private void fillView(Context context, LinearLayout listView) {
            MyAdapter adapter = new MyAdapter(context);
            final int adapterCount = adapter.getCount();
            for (int i = 0; i < adapterCount; i++) {
                View item = adapter.getView(i, null, null);
                listView.addView(item);
            }

    }

1
2
3
4
5
6
7
8
9
10
        <ListView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:drawSelectorOnTop="false"
        android:id="@+id/list1"
        android:layout_weight="1"
        android:cacheColorHint="#00000000"
        android:focusable="false"                  
        >
        </ListView>