Problème de mise à jour des données ListView


Introduction à cette section :

Nous avons déjà appris quelques utilisations de base de ListView, mais si vous êtes prudent, vous constaterez peut-être que nos données Ce qui est défini au début est entièrement statique, mais dans le développement réel, nos données changent souvent de manière dynamique, comme par exemple Si j'ajoute ou supprime une certaine colonne, les données affichées dans la liste doivent également être mises à jour de manière synchrone, nous en discuterons donc dans cette section. Ensuite, commençons cette section sur la question de la mise à jour des données ListView, y compris la mise à jour de toutes et la mise à jour de l'une d'entre elles ! ~


1. Écrivons d'abord une démo normale

D'accord, écrivons d'abord une démo normale, ajustons-la lentement plus tard :

<🎜. >
Classe d'entité :

Data.java

/**
 * Créé par Jay le 2015/9/21 0021.
 */
public class Data {
private int imgId;
contenu de chaîne privé ;

données publiques() {}

données publiques (int imgId, contenu de chaîne) {
this.imgId = imgId;
this.content = content ;
}

public int getImgId() {
return imgId;
}

public String getContent() {
return content;
}

public void setImgId(int imgId) {
this.imgId = imgId;
}

public void setContent(String content) {
content = content;
}
}

Activity布局以及列表项布局

activity_main.xml

<LinearLayout xmlns:android="http ://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android : layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/list_one "
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

item_list.xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android .com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <ImageView <   androïde :id="@+id/txt_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_marginLeft=" 10dp"
        android:textSize="18sp" />

</LinearLayout>

自定义BaseAdapter的实现:MyAdapter.java

MainActivity.java的编写:

classe publique MainActivity étend AppCompatActivity {

    private ListView list_one;
    private MyAdapter mAdapter = null;
    private List<Data> mData = null;
    private Context mContext = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout .activity_main);
        mContext = MainActivity.this;
        bindViews();
        mData = new LinkedList<Data>();
        mAdapter = new MyAdapter((LinkedList<Data >) mData,mContext );
        list_one.setAdapter(mAdapter);
    }

    private void bindViews(){
        list_one = (ListView) findViewById(R.id.list_one);
    }

}

Il peut être exécuté. Après l'avoir exécuté, nous avons constaté que notre page ne contient aucune donnée et est complètement blanche. Cette expérience utilisateur n'est pas bonne. Nous pouvons appeler une méthode setEmptyView(View) de ListView lorsque les données ListView sont vides. Afficher une vue correspondante. De plus, j'ai trouvé que cette méthode est très étrange. La vue ajoutée dynamiquement n'est pas valide et ne peut être affichée que dans ListView. Ajoutez la vue que vous souhaitez afficher lorsque ListView n'a aucune donnée dans le fichier de mise en page et utilisez ce setEmptyView pour la définir. View, il ne s'affichera pas lors du chargement. C'est tellement étrange... Par exemple, lorsqu'il n'y a pas de données, il affichera un "Aucune donnée". TextView, une partie du code est la suivante :

<TextView
android:id="@+id/txt_empty"
android:layout_width="wrap_content"
android :layout_height= "wrap_content"
android:layout_gravity="center"
android:textSize="15pt"
android:textColor="#000000"/>
txt_empty = (T extView) findViewById ( R.id.txt_empty);
txt_empty.setText("No data~");
list_one.setEmptyView(txt_empty);
Bien sûr, en plus de cette méthode, nous pouvons également définir une mise en page avec la même taille et la même position que ListView, puis définissez-la, android:visibility="gone", détermine la taille de la collection mData en code Java, si ==0, Cela signifie qu'il n'y a pas de données, laissez cette mise en page être affichée, et lorsqu'il y a des données, laissez cette mise en page être masquée ~


2 Ajouter un enregistrement

D'accord, obtenons un. bouton Ajouter, non Cliquez pour ajouter un enregistrement à la fois~

Exécution du rendu :

2.gif

Implémentation du code

Dans notre personnalisation Définir une méthode dans BaseAdapter, le contenu de la méthode est le suivant :

public void add(Data data) {
if (mData == null) {
mData = new LinkedIn

Ajoutez ensuite un bouton à la mise en page, puis définissez l'événement. Le code est le suivant :

private Button btn_add;
btn_add = (Button) findViewById(R.id. btn_add);
btn_add.setOnClickListener(this);

@Override
public void onClick(View v) {
switch (v.getId()){
case R. id.btn_add:
          mAdapter.add(new Data(R.mipmap.ic_icon_qitao, "Agenouillez-vous pour Brother Pig~~~ x " + flag)); . C'est aussi simple que cela d'ajouter des données ~ Si vous souhaitez les insérer dans une position spécifique, c'est très bien. Dans notre classe Adapter, ajoutez-en une autre. Écrivez une méthode :
//往特定位置,添加一个元素
public void add(int position,Data data){
    if (mData == null) {
        mData = new LinkedList<>();
    }
    mData.add(position,data);
    notifyDataSetChanged();
}
然后加个按钮,写个事件:


private Button btn_add2;
btn_add2 = (Button) findViewById(R.id.btn_add2);
btn_add2.setOnClickListener(this);

case R.id.btn_add2 :

//la position commence à partir de 0
mAdapter.add(4,new Data(R.mipmap.ic_icon_qitao,"Agenouillez-vous pour Brother Pig~~~ x " + flag )) ;
break;



Rendu en cours d'exécution :


Vous pouvez voir que notre neuvième élément est inséré en cinquième position ~

3. Supprimer un certain élément

De même, nous écrivons deux méthodes, l'une pour supprimer l'objet directement et l'autre pour supprimer en fonction du curseur : >public void delete (Données de données) {3.gif if(mData != null) {

mData.remove(data);

}
notifyDataSetChanged();

}

public void delete(int position) {

if(mData != null) {
mData.remove(position);
}
notifyDataSetChanged();
}


Puis ajoutez deux boutons et appelez ces deux méthodes :


case R.id.btn_remove:
mAdapter.remove(mData_5);
break;
case R.id.btn_remove2:
mAdapter.remove(2);
break;

Rendu des opérations :

4.gif

Sur l'image, nous pouvons voir que le cinquième élément a été supprimé, puis cliquez sur le curseur pour supprimer les données , C'est le troisième élément que je continue de supprimer !


4. Supprimez tous les enregistrements :

C'est plus simple, appelez simplement la méthode clear directement ! Le code de la méthode est le suivant :

public void clear() {
if(mData != null) {
mData.clear();
}
notifyDataSetChanged ();
}

5. Mettre à jour un certain enregistrement

Si vous faites attention, vous auriez dû découvrir qu'après les opérations de modification des données, un notifyDataSetChanged( );Au début, j'ai pensé :

notifyDataSetChanged() redessinera tous les éléments réels de l'interface, ce qui affectera les performances de l'interface utilisateur si la quantité de données. C'est gros, mais si je change un élément, je dois redessiner tous les éléments. C'est définitivement déraisonnable, non ? Alors, j'ai utilisé une méthode stupide Pour modifier la valeur du contrôle dans un Item, j'ai écrit ce code en code Java :

private void updateListItem(int postion,Data mData){
int visiblePosition = list_one. getFirstVisiblePosition();
View v = list_one.getChildAt(postion - visiblePosition);
ImageView img = (ImageView) v.findViewById(R.id.img_icon);
TextView tv = (TextView) v. findViewById(R.id.txt_content);
img.setImageResource(mData.getImgId());
tv.setText(mData.getContent());
}

Plus tard, j'ai discuté avec des amis du groupe et j'ai découvert que j'avais tort :

La méthode notifyDataSetChanged() déterminera si un nouveau rendu est nécessaire si l'élément actuel le fait. pas besoin d'être restitué, Il ne sera pas restitué. Si l'état d'un élément change, la vue sera redessinée, et ce qui est redessiné ne l'est pas. Tous les éléments, à l'exception de l'élément dont l'état d'affichage change ! Nous notifions donc directement la méthode DataSetChange() Ça y est, bien sûr, vous pouvez connaître une autre des méthodes ci-dessus ~


Téléchargement du code :

ListViewDemo3.zip


Résumé de cette section :

D'accord, cette section vous parle de la mise en œuvre de la mise à jour des données dans ListView, bien sûr non seulement ListView, mais aussi d'autres adaptateurs Les contrôles de classe peuvent appeler ces méthodes pour effectuer les mises à jour des données~C'est tout~Merci