Select edittexts text in a listview. How can be do

2019-02-14 14:45发布

问题:

I have a ListView with an EditText on each row working.

I need to select this text on click the edittext to write numbers without erasing or moving the cursor.

Using selectAllonfocus at first works. However, after scrolling the listview, the EditText got crazy and selection doesn't work correctly.

If I execute selectAll in the listener onFocus, then when a touch is made the contextmenu (select word, select all,etc) is shown instead of the selection.

If someone can help.

Thanks.

回答1:

I can't tell what it is that you are trying to do. Perhaps it'd help if you can post some of your relevant source code...

But the fact that it gets crazy when you start scrolling makes me thing you aren't handling the convertView correctly in your adapter getView() method.



回答2:

If you're having problem after scrolling it's the view recycling that's messing you up. You basically need to set up an array to hold the contents of the EditTexts so when you scroll they don't get messed up. You didn't say what was backing your list, but I've got a list with edittexts contained and here's how I handle it (from a cursor, but you could adapt it for an ArrayAdapter):

public class CursorAdapter_EditText extends SimpleCursorAdapter {

    private static Cursor c;
    private Context context;
    public static String[] quantity;
    private int layout;

    public CursorAdapter_EditText(Context context, int layout, Cursor c,
                        String[] from, int[] to) {
        super(context, layout, c, from, to);
        CursorAdapter_EditText.c = c;
        this.context = context;
        this.layout = layout;
        initializeQuantity();    //  Call method to initialize array to hold edittext info
    }

    public static void initializeQuantity() {
        quantity = new String[c.getCount()];    //  Initialize array to proper # of items
        int i = 0;
        while (i < c.getCount()) {              
                        quantity[i] = "";       // set all EditTexts to empty
                        i++;
        }
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null)
                        convertView = View.inflate(context, layout, null);
        final int pos = position;
        View row = convertView;
        c.moveToPosition(position);
        TextView name = (TextView) row.findViewById(R.id.ListItem1);
        EditText qty = (EditText) row.findViewById(R.id.qty);
        qty.setOnFocusChangeListener(new View.OnFocusChangeListener() {  //  Set so EditText will be saved to array when you leave it
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (!hasFocus) {
                    LinearLayout parent = (LinearLayout) v.getParent();            
                    EditText qtyTemp = (EditText) parent.findViewById(R.id.qty);   //  Get a reference to EditText (you could probaly use v here)
                    quantity[pos] = qtyTemp.getText().toString();              // Save contents of EditText to array
                }
            }
        });
        name.setText(c.getString(1));
        unit.setText(c.getString(3));
        qty.setText(quantity[position]);
        return (row);
    }
}

Then I have a button outside the array that processes it back into my database like this:

commit.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
        int i = 0;
        itemCursor.moveToFirst();
        while (itemCursor.isAfterLast() == false) {
            if (CursorAdapter_EditText.quantity[i].equals("")) {
                CursorAdapter_EditText.quantity[i] = "0";
            }
            ;
            int tempQty = Integer
                    .parseInt(CursorAdapter_EditText.quantity[i]);
            if (tempQty != 0) {
                mDbHelper.createListItem(listId, itemCursor
                        .getInt(itemCursor
                                .getColumnIndex(GroceryDB.ITEM_ROWID)),
                        tempQty, 0);
            }
            i++;
            itemCursor.moveToNext();
        }
    }
});


回答3:

I dealt with exactly the same problem by doing the following:

  1. Remove android:descendantFocusability="beforeDescendants" from xml with ListView, android:windowSoftInputMode="adjustPan" from AndroidManifest - they ain't help.
  2. Subclassed EditText

    public class TrickyEditText extends EditText {
    
        private boolean mFocused = false;
        private boolean mTouched = false;
    
        public TrickyEditText(Context context) {
            super(context);
        }
    
        public TrickyEditText(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public TrickyEditText(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        public TrickyEditText(Context context, AttributeSet attrs, int defStyleAttr, int style) {
            super(context, attrs, defStyleAttr, style);
        }
    
        @Override
        public boolean didTouchFocusSelect() {
            if (mTouched && mFocused) {
                return true;
            } else {
                return super.didTouchFocusSelect();
            }
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            mTouched = true;
            return super.onTouchEvent(event);           
        }
    
        @Override
        protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
            mFocused = focused;
            if (!focused) {
                mTouched = false;
            }
            super.onFocusChanged(focused, direction, previouslyFocusedRect);
        }
    }
    
    1. Adapter code

      public class TrickyAdapter extends ArrayAdapter {
      
          .............
      
          @Override
          public View getView(int childPosition, View convertView, final ViewGroup parent) {
      
              .........
      
              TrickyEditText et = ..... //initialize edittext
      
              et.setOnFocusChangeListener(new OnFocusChangeListener() {
      
                  @Override
                  public void onFocusChange(final View v, boolean hasFocus) {
                      if (hasFocus) {
                          v.post(new Runnable() {
      
                              @Override
                              public void run() {
                                  ((EditText)v).selectAll();
                              }
                          });                    
                      }
                  }
              });
      
              .........
          }
      }
      

Although it's working pretty well, it's not the code I'm proud of... If somebody knows a prettier solution, please tell me!



回答4:

On the getView method of your adapter, get your EditView (in this code, edittxt) and do:

    edittxt.post(new Runnable() {
        public void run() {
            edittxt.requestFocusFromTouch();
            edittxt.selectAll();
            InputMethodManager lManager = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE); 
            lManager.showSoftInput(edittxt, 0);
        }
    }); 


回答5:

What I can say about what I asked is that trying to select all text of the listview edittexts don't work properly. So instead of select the text, I show a dialog where the user selects the number or whatever.



回答6:

Not sure if you are still looking for a solution, but I found a way to do it. Add a focus change listener to the edittext in the getView method of your adapter and select all text when focus is received.

public View getView(int position, View convertView, ViewGroup parent) {
    View view = convertView;
    // blah blah blah

    EditText edit = (EditText) view.findViewById(R.id.editTextId);
    edit.setOnFocusChangeListener(new OnFocusChangeListener() {
        @Override
        public void onFocusChange(View view, boolean hasFocus) {
            if (hasFocus)
                ((EditText) view).selectAll();
        }
    });

    return view;
}

I had set windowSoftInputMode to adjustPan for the activity, although I don't think it has any bearing on this matter.

I have tested this on Android 2.3 and 4 and it works.