web-dev-qa-db-fra.com

Edittext dans Listview Android

J'ai Listview avec editext et textview.

Quand je touche sur edittext puis edittext a perdu le focus!

J'ai résolu ce problème en définissant Android:windowSoftInputMode="adjustPan"(AndroidManifest.xml). Maintenant, je touche à edittext plutôt qu'à editext get focus, mais le libellé de l'application et certains éléments bruts de listview disparaissent (partie supérieure).

Je veux avoir le focus lorsque l'utilisateur touche edittext sans étiquette d'application de perte et un peu brut de listview.

Code que j'ai implémenté:

Le code ci-dessous indique la mise au point lorsque l'utilisateur appuie sur edittext, mais le libellé de l'application et certains éléments bruts de la liste de visualisation disparaissent lorsque le clavier virtuel s'affiche.

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

}
19
user1206620

J'avais le même problème. Mon clavier numérique apparaîtrait momentanément avant d'être remplacé par le clavier qwerty et le focus perdant EditText.

Le problème est que le clavier apparaissant fait perdre votre focus à votre EditText. Pour éviter cela, insérez les éléments suivants dans votre fichier AndroidManifest.xml pour l'activité (ou les activités) appropriée (s):

Android:windowSoftInputMode="adjustPan"

Voir Android documentation :

Lorsque la méthode de saisie apparaît à l'écran, la quantité d'espace disponible pour l'interface utilisateur de votre application est réduite. Le système décide comment ajuster la partie visible de votre interface utilisateur, mais il risque de ne pas réussir. Pour garantir le meilleur comportement de votre application, vous devez spécifier la manière dont vous souhaitez que le système affiche votre interface utilisateur dans l'espace restant.

Pour déclarer votre traitement préféré dans une activité, utilisez l'attribut Android:windowSoftInputMode dans l'élément <activity> de votre manifeste avec l'une des valeurs "ajuster".

Par exemple, pour vous assurer que le système redimensionne votre mise en page en fonction de l'espace disponible (ce qui garantit que tout le contenu de votre mise en page est accessible (même s'il nécessite probablement un défilement) - utilisez "adjustResize"

6
Cyrille

Sans voir votre code, comment pouvons-nous suggérer la solution possible à votre problème. Continuez donc à poster du code possible chaque fois que vous posez une question.

Cependant, ici, j'ai trouvé un tutoriel pour implémenter Android Focusable EditText dans ListView . Passez en revue l’exemple et essayez de le mettre en œuvre ou trouvez la solution à votre problème.

4
Paresh Mayani

J'ai résolu récemment ce problème "Mettre EditText dans ListView en tant qu'élément". Je ne suis pas très bon en anglais. Donc, s'il y a quelque chose que je n'explique pas clairement, merci de me le dire.

Nous savons que ListView peut faire défiler verticalement et nous voulons mettre EditText dans ListView en tant qu’élément. 

Premier: Ajouter 

Android: windowSoftInputMode = "ajuster-redimensionner" 

dans votre fichier AndroidManifest.xml au niveau du nœud d'activité.

Second: Nous créons un pojo en tant que source de données de modèle pour contrôler l'état EditText

Line.Java

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

    get set method and so on...
}

Third: Nous écrivons un adaptateur pour adapter EditText à 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>

Adaptateur:

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

Terminé!

Vous pouvez lire plus de détails dans mon github.

Démo: https://github.com/Aspsine/EditTextInListView

3
Aspsine

ListView recréez la vue, Essayez d'utiliser une LinearLayout dans ScrollView, puis dans votre code, utilisez une runOnUiThread pour remplir votre vue dans un autre fil de discussion comme celui-ci.

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

    }
0
Ubirajara Erthal