2017-08-09 1 views
0

Ich komme nach langer Zeit wieder zu Android und ich bin ein bisschen mit einem Problem fest.
Die App besteht aus einer Liste von Layouts, die jeweils von einem Modell über den Adapter unterstützt werden.
Jedes Layout hat mehrere Ansichten, von denen einer ein Spinner ist.
Ich möchte die Daten im Adapter ändern, wenn Sie den Wert des Drehfelds ändern, aber ich weiß nicht, wie Sie auf das Objekt im Adapter verweisen.Zugriff auf ein Adapter-Objekt aus einer Ansicht in der ListView

public class MainActivity extends AppCompatActivity { 
    ArrayList<Troop> values = new ArrayList<Troop>(); 
    MySimpleArrayAdapter adapter; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     values.add(new Troop()); 

     final ListView listView =(ListView) findViewById(R.id.listview); 

     adapter = new MySimpleArrayAdapter(
       this, 
       values); 
     listView.setAdapter(adapter); 
    } 

    public class Troop { 
     private String weapon; 
     private int bs; 
     private int total_modifier; 

     public Troop() { 

     } 

     public int getBs() { 
      return bs; 
     } 

     public void setBs(int bs) { 
      this.bs = bs; 
     } 
    } 

    public class MySimpleArrayAdapter extends ArrayAdapter { 
     private final Context context; 
     private ArrayList<Troop> troopers; 
     private String[] possible_bs = new String[] {"10", "11", "12", "13", "15", "16"}; 

     public MySimpleArrayAdapter(Context context, ArrayList<Troop> values) { 
      super(context, -1, values); 
      this.context = context; 
      this.troopers = values; 
     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
       LayoutInflater inflater = (LayoutInflater) context 
         .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
       View rowView = inflater.inflate(R.layout.rowlayout, parent, false); 

       Spinner bs_spinner = rowView.findViewById(R.id.bs_spinner); 
       ArrayAdapter<String> bs_adapter = new ArrayAdapter<String>(
         context, 
         android.R.layout.simple_spinner_dropdown_item, 
         possible_bs); 
       bs_spinner.setOnItemSelectedListener(new CustomOnItemSelectedListener()); 
       bs_spinner.setAdapter(bs_adapter); 
      return rowView; 
     } 

    } 

    public class CustomOnItemSelectedListener implements AdapterView.OnItemSelectedListener { 

     public void onItemSelected(AdapterView<?> parent, View view, int pos,long id) { 
     // I want to call getBs on the Trooper correspoding to this view here 
     } 

     @Override 
     public void onNothingSelected(AdapterView<?> arg0) { 
      // TODO Auto-generated method stub 
     } 

    } 
} 
+0

Sie sollten 'erweitert ArrayAdapter ' –

+0

Vielen Dank für Ihre Antwort. Die Frage ist, wie man von der onItemSelected-Methode auf den Adapter zugreift. –

+0

Es ist ein Kommentar, keine Antwort;) Welcher Adapter? –

Antwort

0

Hier ist eine Menge los, die ich ansprechen würde. Lassen Sie uns zuerst über Ihre Unterklasse ArrayAdapter sprechen. Wie in einem Kommentar zu Ihrer Frage erwähnt, sollten Sie ihn in extends ArrayAdapter<Troop> ändern. Dies führt dazu, dass getItem()Troop anstelle von Object zurückgibt.

Sie müssen Ihre eigenen Felder context oder troopers nicht speichern. Die grundlegende Implementierung ArrayAdapter speichert einen Kontext im Feld mContext und Sie können auf es über getContext() zugreifen. Darüber hinaus speichert es die Hintergrunddaten im Feld mObjects, und Sie können auf es über getItem() zugreifen.

Schließlich, wenn alle Elemente in Ihrem Adapter den gleichen possible_bs Wert teilen, sollten Sie es zu einer Konstante machen.

Als nächstes sprechen wir über die AdapterView.OnItemSelectedListener.

Sie müssen einen Weg, die Position zu kennen (von Ihrem MySimpleArrayAdapter) Ihre Spinner lebt in (als auf die Position des Elements gegen innerhalb der Spinner der Benutzer ausgewählt hat). Ich empfehle, diese Position an einen Konstruktor zu übergeben und sie als privates Endfeld zu speichern.

Um am Adapter zu erhalten aus dem Inneren des Spinner, können Sie die Adapter das AdapterView Argument Sicherung zugreifen parent.getAdapter() durch den Aufruf, und dann auf die gewünschte Art gegossen.

Alle zusammen, sind Sie mit dieser links:

public static class MySimpleArrayAdapter extends ArrayAdapter { 

    private static final String[] POSSIBLE_BS = new String[] {"10", "11", "12", "13", "15", "16"}; 

    public MySimpleArrayAdapter(Context context, ArrayList<Troop> values) { 
     super(context, -1, values); 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     LayoutInflater inflater = (LayoutInflater) getContext() 
       .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     View rowView = inflater.inflate(R.layout.rowlayout, parent, false); 

     Spinner bs_spinner = rowView.findViewById(R.id.bs_spinner); 
     ArrayAdapter<String> bs_adapter = new ArrayAdapter<>(
       getContext(), 
       android.R.layout.simple_spinner_dropdown_item, 
       POSSIBLE_BS); 
     bs_spinner.setOnItemSelectedListener(new CustomOnItemSelectedListener(position)); 
     bs_spinner.setAdapter(bs_adapter); 
     return rowView; 
    } 

} 

private static class CustomOnItemSelectedListener implements AdapterView.OnItemSelectedListener { 

    private final int troopPosition; 

    private CustomOnItemSelectedListener(int troopPosition) { 
     this.troopPosition = troopPosition; 
    } 

    @Override 
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 
     MySimpleArrayAdapter adapter = (MySimpleArrayAdapter) parent.getAdapter(); 
     int bs = adapter.getItem(troopPosition).getBs(); 
    } 

    @Override 
    public void onNothingSelected(AdapterView<?> parent) { 

    } 
} 
+0

Wäre der Positionsparameter nicht die Position des auf dem Drehfeld ausgewählten Elements und nicht die Position des Elements in der Listenansicht? –

+0

Ja, der Parameter 'position' zu 'onItemSelected()' ist die Position des ausgewählten Elements im 'Spinner'. Aus diesem Grund müssen Sie 'troopPosition' an den' OnItemSelectedListener' übergeben und diesen stattdessen verwenden. –

0

Sie können in der anonymen Klasse bewegen.

Sie möchten beide Positionselemente abrufen, wenn Sie sowohl das aktuelle ListView-Element als auch die innere Adapterposition wünschen.

Es wahrscheinlich saubere Wege, dies zu tun, aber es ist die erste Idee, die ich hatte

public class MySimpleArrayAdapter extends ArrayAdapter<Troop> { 
    private final Context context; 
    private ArrayList<Troop> troopers; 
    private String[] possible_bs = new String[] {"10", "11", "12", "13", "15", "16"}; 

    @Override 
    public View getView(final int position, View convertView, ViewGroup parent) { 
      LayoutInflater inflater = (LayoutInflater) context 
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      View rowView = inflater.inflate(R.layout.rowlayout, parent, false); 
      Spinner bs_spinner = rowView.findViewById(R.id.bs_spinner); 

      final ArrayAdapter<String> bs_adapter = new ArrayAdapter<String>(
        context, 
        android.R.layout.simple_spinner_dropdown_item, 
        possible_bs); 
      bs_spinner.setAdapter(bs_adapter); 

      bs_spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 

       @Override 
       public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { 
        // You can access MySimpleArrayAdapter.this or bs_adapter 
        Troop t = troopers.get(position); // or getItem(position); 
        String bs = possible_bs[pos]; 
       } 

       @Override 
       public void onNothingSelected(AdapterView<?> arg0) { 
        // TODO Auto-generated method stub 
       } 

      }); 

     return rowView; 
    } 
Verwandte Themen