2016-08-12 5 views
2

Gemeinschaft! Ich brauche eine Hilfe bei der Aktualisierung von unsichtbaren Elementen in ListView. Es geht nicht um den Inhalt von Elementen, sondern um die Ansichtsdarstellung von Elementen. Ok, lass mich dir mein Beispiel zeigen. Ich habe ein String-Array:Wie aktualisiert man bestimmte Ansichten unsichtbarer Objekte in ListView? [Android]

<string-array name="reminder_notifications"> 
    <item>15 minutes before</item> 
    <item>30 minutes before</item> 
    <item>1 hour before</item> 
    <item>1.5 hour before</item> 
    <item>5 hours before</item> 
    <item>8 hours before</item> 
    <item>1 day before</item> 
</string-array> 

In Aktivität i Adapter erstellt habe:

adapterNotifications = ArrayAdapter.createFromResource(this, R.array.reminder_notifications, R.layout.dialog_list_multiple_choise); 

Nach, mit einigen Methoden i für aktuelle Erinnerung whitch Elemente aus String-Array sind vorhanden berechnen. Z.B. Wenn der Benutzer um 16:00 Uhr eine Erinnerung für 16:45 setzt, kann er nur die Elemente 15 minutes before und 30 minutes before auswählen. Andere Elemente sollten deaktiviert sein. Also, nach google habe ich herausgefunden, wie der Zugang zu unsichtbar Listview Kind bei bestimmten Position zu bekommen:

public View getViewByPosition(int position, ListView listView) { 
    final int firstListItemPosition = listView.getFirstVisiblePosition(); 
    final int lastListItemPosition = firstListItemPosition + listView.getChildCount() - 1; 
    if (position < firstListItemPosition || position > lastListItemPosition) { 
     return listView.getAdapter().getView(position, listView.getChildAt(position), listView); 
    } else { 
     final int childIndex = position - firstListItemPosition; 
     return listView.getChildAt(childIndex); 
    } 
} 

Jetzt bin ich mit dem letzten Problem konfrontiert (hoffe ich) - wie Artikel anzeigen aktualisieren, die ich von Methode oben? Ich habe versucht, diese zu nutzen:

View v = getViewByPosition(position, lvNotifications); 
v.setEnabled(true); 

Aber es Neuigkeiten stehen erst nach dem ersten Dialog zu öffnen, eine andere Worte, die ich das Dialogfenster mit Listview zu öffnen haben, schließen Sie es und wieder zu öffnen. Nur in diesem Fall werde ich eine aktualisierte Ansicht erhalten. Ich weiß, dass mein Englisch ist schrecklich, so gibt es Screenshots unten:

Hauptdialogfeld. Bevor Sie den Dialog mit ListView öffnen Main dialog. Before opening the dialog with ListView

Listenansicht-Dialog. Erste Eröffnung. Keine Elemente sind deaktiviert. WRONG List view dialog. First opening. No items are disabled. WRONG

Listenansichtsdialog. Zweite Öffnung. 5 Gegenstände sind deaktiviert. RECHTS List view dialog. Second opening. 5 items are disabled. RIGHT

Vielen Dank.

Antwort

1

Sie haben das Problem von der falschen Seite angegangen. Sie sollten die Ansichten nicht von außerhalb eines Adapters bearbeiten, dafür ist der Adapter gedacht. Schreiben Sie stattdessen Ihren eigenen Adapter. Machen Sie es wie folgt aus:

import android.content.Context; 
import android.support.annotation.NonNull; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ArrayAdapter; 
import android.widget.BaseAdapter; 
import android.widget.CheckBox; 
import android.widget.CompoundButton; 
import android.widget.TextView; 

/** 
* A {@link ArrayAdapter} to let the user select multiple notification times. 
*/ 
public class ReminderNotificationsAdapter extends BaseAdapter implements CompoundButton.OnCheckedChangeListener { 

    /** 
    * A array with all currently selected entries 
    */ 
    private boolean[] mSelected; 

    /** 
    * A array with all enabled entries 
    */ 
    private boolean[] mEnabled; 

    /** 
    * The items to be shown 
    */ 
    private String[] mItems; 

    /** 
    * A {@link Context} 
    */ 
    private Context mContext; 

    /** 
    * Creates a new instance 
    * 
    * @param context a {@link Context} 
    * @param items all selectable items 
    * @param checkedItems all selected items. This array will be updated with the users selectiion 
    * @param enabledItems all enabled items 
    */ 
    public ReminderNotificationsAdapter(Context context, String[] items, boolean[] checkedItems, boolean[] enabledItems) { 
     // Check array sizes 
     if(items.length != checkedItems.length || checkedItems.length != enabledItems.length) { 
      throw new RuntimeException("All arrays must be the same size"); 
     } 

     // Add all and store params 
     this.mContext = context; 
     this.mItems = items; 
     this.mSelected = checkedItems; 
     this.mEnabled = enabledItems; 

    } 

    @Override 
    public int getCount() { 
     return this.mItems.length; 

    } 

    @Override 
    public String getItem(int i) { 
     return this.mItems[i]; 

    } 

    @Override 
    public long getItemId(int i) { 
     return this.getItem(i).hashCode(); 

    } 

    @NonNull 
    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     View v = convertView; 

     // Create view if not provided to convert 
     if(v == null) { 
      v = LayoutInflater.from(this.mContext).inflate(R.layout.dialog_list_multiple_choise, parent, false); 
     } 

     // Prepare text view 
     TextView tv = (TextView) v.findViewById(android.R.id.text1); 
     tv.setText(this.getItem(position)); 
     tv.setEnabled(this.isEnabled(position)); 

     // Prepare checkbox 
     CheckBox cb = (CheckBox) v.findViewById(android.R.id.checkbox); 
     cb.setTag(position); 
     cb.setChecked(this.mSelected[position]); 
     cb.setEnabled(this.isEnabled(position)); 
     cb.setOnCheckedChangeListener(this); 

     // Return view 
     return v; 

    } 

    @Override 
    public boolean isEnabled(int position) { 
     return this.mEnabled[position]; 

    } 

    @Override 
    public void onCheckedChanged(CompoundButton compoundButton, boolean b) { 
     this.mSelected[(Integer) compoundButton.getTag()] = b; 

    } 
} 

Und es wie folgt verwenden: Wenn Sie

@Override 
public void onClick(View view) { 
    // Tell what string should be shown 
    String[] entries = this.getResources().getStringArray(R.array.reminder_notifications); 

    // Tell what entries should be already selected 
    final boolean[] selectedEntries = new boolean[entries.length]; 
    selectedEntries[2] = true; 

    // Tell what entries should be enabled 
    boolean[] enabledEntries = new boolean[entries.length]; 
    enabledEntries[0] = true; 
    enabledEntries[1] = true; 
    enabledEntries[2] = true; 
    enabledEntries[3] = true; 

    // Create the adapter 
    ReminderNotificationsAdapter a = new ReminderNotificationsAdapter(this, entries, selectedEntries, enabledEntries); 

    // Create and show the dialog 
    new AlertDialog.Builder(this) 
      .setTitle("Add notification") 
      .setAdapter(a, null) 
      .setPositiveButton("Set", new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialogInterface, int i) { 
        // Do what you want to do with the selected entries 
        Toast.makeText(MainActivity.this, Arrays.toString(selectedEntries), Toast.LENGTH_SHORT).show(); 

       } 
      }) 
      .setNegativeButton("Dismiss", null) 
      .show(); 

} 

ich einfach ein boolean-Array verwendet zu erklären, welche Einträge sollten aktiviert und ausgewählt werden, können Sie etwas elegantere es tun wollen. Die Auswahl des Benutzers wird in dem Array aktualisiert, das dem Konstruktor des Adapters zur Verfügung steht. Die Alertdialog sieht wie folgt aus:

Screenshot

Die gesamte Beispiel App here.

+0

Mann, du bist einfach großartig. Vielen Dank! Und ein großes Dankeschön! Sag mir bitte was ist besser CheckedTextView oder TextView + CheckBox? –

+1

CheckedTextView soll mit ListView und setMultipleChoiceItems (...) und setSingleChoiceItems (...) gut spielen und nicht alleine oder als normale Ansicht in meiner Lösung verwendet werden. Verwenden Sie ein TextView und ein RelativeLayout, wenn dies richtig gemacht wird, unterstützt dies auch RTL-Layouts und macht keinen visuellen Unterschied. Sehen Sie sich das Layout an, das ich am Ende meiner Antwort im GitHub Repo verlinkt habe. Ich habe ein paar kleine Änderungen an meiner Lösung vorgenommen (ArrayAdapter durch BaseAdapter ersetzt, einige Paddings geändert) – crysxd

Verwandte Themen