2016-06-20 16 views
0

Ich habe eine benutzerdefinierte DialogFragment mit einem ListView in seinem Layout mit dem Ziel, eine Single-Choice-Liste von Elementen zu sein. Ich instanziiert es mit einem selectedItemId Parameter und ich stelle es auf die Liste des ArrayAdapter so kann ich das aktuelle ausgewählte Element in der getView() Methode wie folgt markieren:Android ArrayAdapter das seltsame Verhalten von getView bei der Hervorhebung von Artikel

public ItemSelectionListAdapter(Context context, List<Item> items, String selectedItemId) { 
     super(context, RESOURCE); 
     this.items = items; 
     this.selectedItemId = selectedItemId; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     if (convertView == null) { 
      convertView = View.inflate(getContext(), RESOURCE, null); 
     } 

     Item item = items.get(position); 

     TextView textView = (TextView) convertView; 
     textView.setText(item.getName()); 

     String itemId = item.getId(); 

     Log.d(TAG, "Current item id: " + itemId); 
     Log.d(TAG, "Selected item id: " + selectedItemId); 

     if (itemId.equals(selectedItemId)) { 
      textView.setTextColor(ContextCompat.getColor(getContext(), R.color.primaryColor)); 
      textView.setTypeface(textView.getTypeface(), Typeface.BOLD); 
     } 

     return convertView; 
    } 

Der Standardpunkt (wenn kein Element noch ausgewählt wurde) ist an Position 0, so zeigt dieses Bild die erwartete Ansicht:

enter image description here

jedoch nur, wenn ich andere Artikel wählen beide hervorgehoben werden:

enter image description here

Der Code ist wirklich einfach, aber das Element an Position: 0 wird immer hervorgehoben. Ich habe bereits überprüft, ob selectedId aktualisiert wird und ja, es ist immer die ID des zuletzt ausgewählten Artikels. Ich habe auch, dass alle Teile vorhanden sind eindeutige IDs und ja, sie haben:

Dies ist de log zum ersten Mal die Dialog zeigt:

06-20 14:26:37.677 7860-7860/xxx D/ADAPTER: getCount() -> 6 
06-20 14:26:37.677 7860-7860/xxx D/ADAPTER: Current item id: -2 
06-20 14:26:37.678 7860-7860/xxx D/ADAPTER: Selected item id: -2 
06-20 14:26:37.678 7860-7860/xxx D/ADAPTER: Current item id: 3 
06-20 14:26:37.678 7860-7860/xxx D/ADAPTER: Selected item id: -2 
06-20 14:26:37.678 7860-7860/xxx D/ADAPTER: Current item id: 4 
06-20 14:26:37.679 7860-7860/xxx D/ADAPTER: Selected item id: -2 
06-20 14:26:37.679 7860-7860/xxx D/ADAPTER: Current item id: 5 
06-20 14:26:37.679 7860-7860/xxx D/ADAPTER: Selected item id: -2 
06-20 14:26:37.680 7860-7860/xxx D/ADAPTER: Current item id: 6 
06-20 14:26:37.680 7860-7860/xxx D/ADAPTER: Selected item id: -2 
06-20 14:26:37.680 7860-7860/xxx D/ADAPTER: Current item id: 7 
06-20 14:26:37.680 7860-7860/xxx D/ADAPTER: Selected item id: -2 

Und das ist ein anderes Mal auf einige Artikel klicken:

06-20 14:28:24.759 7860-7860/xxx D/ADAPTER: getCount() -> 6 
06-20 14:28:24.760 7860-7860/xxx D/ADAPTER: Current item id: -2 
06-20 14:28:24.760 7860-7860/xxx D/ADAPTER: Selected item id: 4 
06-20 14:28:24.760 7860-7860/xxx D/ADAPTER: Current item id: 3 
06-20 14:28:24.761 7860-7860/xxx D/ADAPTER: Selected item id: 4 
06-20 14:28:24.761 7860-7860/xxx D/ADAPTER: Current item id: 4 
06-20 14:28:24.761 7860-7860/xxx D/ADAPTER: Selected item id: 4 
06-20 14:28:24.762 7860-7860/xxx D/ADAPTER: Current item id: 5 
06-20 14:28:24.762 7860-7860/xxx D/ADAPTER: Selected item id: 4 
06-20 14:28:24.762 7860-7860/xxx D/ADAPTER: Current item id: 6 
06-20 14:28:24.763 7860-7860/xxx D/ADAPTER: Selected item id: 4 
06-20 14:28:24.763 7860-7860/xxx D/ADAPTER: Current item id: 7 
06-20 14:28:24.763 7860-7860/xxx D/ADAPTER: Selected item id: 4 

Was mache ich falsch?

EDIT: Sobald ein Element geklickt wird, seine ID in der Aktivität gespeichert wird (es wird die nächste selectedItemId sein) und der Dialog zerstört wird. Der Adapter erstellt also jedes Mal, wenn ein Element ausgewählt wird.

EDIT 2: Dies ist der wichtige Code des Dialogs, in dem ich den Adapter instanziiert und an die ListView jedes Mal setzen den Dialog erstellt wird.

@Bind(R.id.item_list) 
    protected ListView list; 

    private String selectedItemId; 
    private List<Item> items; 

    public static ItemSelectionDialog newInstance(String selectedItemId) { 
     ItemSelectionDialog dialog = new ItemSelectionDialog(); 

     Bundle args = new Bundle(); 
     args.putString(ARG_ITEM_ID, selectedItemId); 
     dialog.setArguments(args); 

     return dialog; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     selectedItemId = getArguments().getString(ARG_ITEM_ID); 
     items = getItemsFromDataBase(); 
    } 

    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 
     View view = View.inflate(getContext(), R.layout.dialog_item_selection, null); 
     ButterKnife.bind(this, view); 

     // Here I instantiate the adapter with a different selectedItemId each time 
     list.setAdapter(new ItemSelectionListAdapter(getContext(), items, selectedItemId)); 

     return new AlertDialog.Builder(getActivity()) 
      .setView(view) 
      .create(); 
    } 

    // This is a normal OnItemClickListener attached to the ListView 
    @OnItemClick(R.id.item_list) 
    public void onItemClick(int position) { 
     // Here I store the ID in the host activity, which implements a custom "OnItemSelectedListener" 
     listener.onItemSelected(items.get(position)); 
     dismiss(); 
    } 

Antwort

1

Sie haben Code zur Auswahl, aber nicht zum Entfernen dieser Auswahl. Wo ist sonst noch Teil? Erstmals Punkt 0. Position wird eine hervorgehoben, das nächste Mal andere ausgewählt werden, aber Sie sind nicht Auswahl von vorherigen entfernen, die

if (itemId.equals(selectedItemId)) { 
     textView.setTextColor(ContextCompat.getColor(getContext(), R.color.primaryColor)); 
     textView.setTypeface(textView.getTypeface(), Typeface.BOLD); 
    }else{ 
textView.setTextColor(ContextCompat.getColor(getContext(),R.color.black)); 
     textView.setTypeface(textView.getTypeface(), Typeface.NORMAL); 
} 
+0

Die Liste in einem Dialog, die zerstört und Jedes Mal neu erstellt, so dass es nicht notwendig ist * Code * abzuwählen. Entschuldigung, ich sollte es angeben. – josemigallas

+0

jedes Mal standardmäßig 0. Position gewählt dann ausgewählte Position, deshalb ist 0th Position immer ausgewählt – Pr38y

+0

Wenn die App startet, ist die selectedItemId -2, das ist das Standardelement. Das ist nur für das ** erste Mal ** der Dialog wird angezeigt, wenn noch kein Gegenstand ausgewählt wurde. – josemigallas

0

an der 0. Position Wenn Sie jedes Mal Listenansicht des Dialogs erstellst weiteren hinzufügen Boolean zu Item-Klasse, standardmäßig wäre es falsch, dann Sie sollten onItemClick zu der ListView hinzufügen und aktualisieren Sie Ihre Artikel Datenstruktur entsprechend der Position von onItemClick Rückruf, stellen Sie sicher, alle Elemente ausgewählten Feld auf falsch vor der Aktualisierung zu initialisieren das ausgewählte Element in der Datenstruktur der Elemente. Das letzte, was müssen Sie tun, fügen Sie einfach, was @ Pr38y kommentierte aber mit einer wenig Änderung statt mit

if(itemId.equals(selectedItemId)) 

Verwendung dieses:

if(item.isSelected()) 
+0

Ich weiß bereits, welches Element dank der ID ausgewählt wurde, daher wäre das Hinzufügen eines Booleschen redundant. – josemigallas

+0

Was ist selectedItemId? Sie könnten auch nur die ausgewählte Position des ausgewählten Elements innerhalb Ihres Adapters speichern –

+0

Wieder ist der Adapter verloren, sobald der Dialog zerstört wird, die einzige Sache, die ich speichere, ist die selectedItemId, die die ID des letzten Gegenstandes ist im Dialog ausgewählt. – josemigallas