Edittext in Listview android

45,144

Solution 1

I was having the same problem. My numberic keyboard would momentarily appear before being replaced by the qwerty keyboard and the EditText losing focus.

The problem is that the keyboard appearing makes your EditText lose focus. To prevent this put the following in your AndroidManifest.xml for the appropriate Activity (or Activities):

android:windowSoftInputMode="adjustPan"

See Android documentation:

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 <activity> 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"

Solution 2

Without seeing your code, how can we suggest the possible solution for your problem. So keep practice of posting possible code whenever you ask any question.

However, here i have found one tutorial for implementing Android Focusable EditText inside ListView. Go through the example and try to implement in your way or find out the solution for your problem.

Solution 3

I solved this "Putting EditText in ListView as an item" problem recently. I am not very good at English. So if there's something I don't explain clearly please tell me.

We know ListView can be scrolled verticaly and we want to put EditText in ListView as an item.

First: Add

android:windowSoftInputMode="adjustResize"

in your AndroidManifest.xml at the activity node.

Second: We create an pojo as model data source to control EditText state

Line.java

public class Line{
    int num;
    String text;
    boolean focus;

    get set method and so on...
}

Third: We write an adapter to adapt EditText to ListView.

Item item_line.xml:

<?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>

Adapter:

@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;
}

All done!

You can read more details in my github.

Demo: https://github.com/Aspsine/EditTextInListView

Share:
45,144
Admin
Author by

Admin

Updated on July 09, 2022

Comments

  • Admin
    Admin almost 2 years

    I have Listview with editext and textview.

    When i touch on edittext then edittext lost focus!

    I resolved this problem by setting android:windowSoftInputMode="adjustPan"(AndroidManifest.xml). Now i touch on edittext than editext get focus but application label and some raw of listview disappear(top part).

    I want to get focus when user touch on edittext without loss application label and some raw of listview.

    Code that i have implemented :

    Below coding get focus when user touch on edittext but application label and some raw of listview disappear when soft keypad pop up.I want to get focus when user touch on edittext without loss application label and some raw of listview.

    1)AndroidManifest.xml

    <application android:icon="@drawable/icon" android:label="@string/app_name">
            <activity android:name=".MyListViewDemoActivity"
                      android:label="@string/app_name"
                      android:windowSoftInputMode="adjustPan"
                      >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
    
    </application>
    

    2) raw_layout.xml

    <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

    <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

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