Android如何在ListView中使EditText可编辑

Posted

技术标签:

【中文标题】Android如何在ListView中使EditText可编辑【英文标题】:Android how to make EditText editable inside a ListView 【发布时间】:2012-02-19 09:54:18 【问题描述】:

我有一个ListView,每个项目中都有编辑文本,我想知道如何使EditText 可编辑。如果我将android:windowSoftInputMode="adjustPan" 设置到清单中似乎可以正常工作,但仅限于一些设备。在某些设备上,软键盘会覆盖编辑文本。

另一方面,如果我不将android:windowSoftInputMode="adjustPan" 放入清单中,则在显示软键盘后EditText 会失去焦点,我必须多次触摸EditText 才能使其被选中并且可以写在里面。

请帮我解决这个问题。

注意:我看过这篇文章:Focusable EditText inside ListView,但没有任何帮助,除此之外我还有其他问题

【问题讨论】:

【参考方案1】:

在尝试使用EditTextsListView 内创建接口失败后,我只能对您说“不要!”。当你有足够的项目需要滚动ListView,焦点会在这里和那里跳跃,你必须保存EditText 的状态等等,你会遇到更多麻烦。似乎一般的想法是在ListView 中使用EditText 是不值得的。

经过大量研究,我可以建议以下对我有帮助的方法: 我继承了ListView 并重写了 layoutChildren 方法,在其中我执行以下操作:

@Override
protected void layoutChildren() 
    super.layoutChildren();
    final EditText tv = (EditText)this.getTag();
    if (tv != null)
    
        Log.d("RUN", "posting delayed");
        this.post(new Runnable() 

            @Override
            public void run() 
                Log.d("RUN", "requesting focus in runnable");
                tv.requestFocusFromTouch();
                tv.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN , tv.getWidth(), tv.getHeight(), 0));
                tv.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP , tv.getWidth(), tv.getHeight(), 0));
            
        );
    

当我知道哪个EditText 应该获得焦点时(当我的适配器getView 被调用时我知道这一点)我将这个特定的EditText 设置为ListView 的标签。然后 ListView 自行布局,我的帖子线程已排队。它运行并请求焦点,但是由于在我的情况下还不够,我还生成了两个 MotionEvents 来简单地模拟点击。显然这足以让软键盘出现。 这背后的原因在此处的答案中进行了解释: Android Actionbar Tabs and Keyboard Focus

【讨论】:

【参考方案2】:

我为此做了一个解决方法..也许会帮助某人

public class EditTextListAdapter extends BaseAdapter 

    /* notes list */
    private ArrayList<SomeData> mSomeData = null;
    /* layout inflater instance */
    private LayoutInflater mInflater;
    /* activity context */
    private Context mContext;

    /* ensure that this constant is greater than the maximum list size */
    private static final int DEFAULT_ID_VALUE = -1;
    /* used to keep the note edit text row id within the list */
    private int mNoteId = DEFAULT_ID_VALUE;

    /**
     * EditTextListAdapter adapter class constructor
     *
     * @param context               activity context
     */
    public FirstTimesListAdapter(Context context) 

        /* get a layout inflater instance */
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        /* load the data */
        mSomeData = SomeData.instance().getData(); 
        /* keep the context */
        mContext = context;
    

    /**
     * Returns the selected item
     *
     * @return selected item
     */
    public int getSelectedItem() 
        return mSelectedItem;
    

    public int getCount() 
        return mSomeData.size();
    

    public Object getItem(int i) 
        return mSomeData.get(i);
    

    public long getItemId(int i) 
        return i;
    

    public View getView(final int index, View recycledView, ViewGroup viewGroup) 

        ViewHolder viewHolder;

        if (recycledView == null) 
            /* inflate the list item */
            recycledView = mInflater.inflate(R.layout.listview_item_with_edit_text, viewGroup, false);
            /* get link to the view holder views */
            viewHolder = new ViewHolder();
            viewHolder.note = (EditText) recycledView.findViewById(R.id.first_times_note);
            recycledView.setTag(viewHolder);
         else 
            /* reuse the same views we load the first time */
            viewHolder = (ViewHolder) recycledView.getTag();
        

        /* display some notes */
        viewHolder.note.setText(mSomeData.getNotes());

        /* if the last id is set, the edit text from this list item was pressed */
        if (mNoteId == index)  

            /* make the edit text recive focus */
            viewHolder.note.requestFocusFromTouch();
            /* make the edit text's cursor to appear at the end of the text */
            viewHolder.note.setSelection(viewHolder.note.getText().length());

            /* reset the last id to default value */
            mNoteId = DEFAULT_ID_VALUE;
        

        /* set a touch listener on the edit text just to record the index of the edit text that was pressed */
        viewHolder.note.setOnTouchListener(new View.OnTouchListener() 
            public boolean onTouch(View view, MotionEvent motionEvent) 
                if (motionEvent.getAction() == MotionEvent.ACTION_UP) 
                    /* get the index of the touched list item */
                    mNoteId = index;
                
                return false;
            
        );

        return recycledView;
    

    static class ViewHolder         
        /* note input */
        EditText note;
    


【讨论】:

以上是关于Android如何在ListView中使EditText可编辑的主要内容,如果未能解决你的问题,请参考以下文章

如何在运行时在android中使部分文本加粗?

如何在Android中使高度超过wrap_content?

如何在颤动中使我的文本与 listview.builder 一起滚动

如何在 Jquery Mobile ListView 控件中使图像垂直居中?

安卓出现错误: java.lang.ClassCastException: android.widget.TextView cannot be cast to android.widget.EditT

如何在 Flutter 中使屏幕可滚动?