2017-08-09 63 views
0

很久以後,我回到Android,我有點卡住了一些問題。
該應用程序由佈局列表組成,每個佈局都通過適配器由模型支持。
每個佈局有幾個視圖,其中之一是一個微調。
我想在更改微調器的值時修改適配器中的數據,但我不知道如何引用適配器中的對象。如何從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

你應該'擴展ArrayAdapter ' –

+0

謝謝您的回答。問題是,如何從onItemSelected方法訪問適配器? –

+0

這是一個評論,而不是答案;)哪個適配器? –

回答

0

這裏有很多我會談到的。首先,我們來談談你的ArrayAdapter子類。

正如您對問題的評論中所述,您應該將其更改爲extends ArrayAdapter<Troop>。這將導致getItem()返回Troop而不是Object

您不需要存儲您自己的contexttroopers字段。基本的ArrayAdapter實現在mContext字段中存儲了一個上下文,您可以通過getContext()訪問它。此外,它將備份數據存儲在mObjects字段中,您可以通過getItem()訪問它。

最後,如果適配器中的所有項目要共享相同的possible_bs值,則應該將其設置爲常量。

接下來讓我們來談談AdapterView.OnItemSelectedListener

您需要一種方法來知道哪些位置(從MySimpleArrayAdapter)您Spinner住在(相對於該項目的位置內Spinner用戶選擇)。我建議將這個位置傳遞給構造函數,並將其保存爲私有的最終字段。

要獲取從Spinner內的適配器,您可以訪問Adapter通過調用parent.getAdapter()來頭AdapterView參數,然後將其投射到您想要的類型。

總之,你留下了這一點:

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

位置參數不是位置在微調器上選擇的項目而不是元素在列表視圖中的位置? –

+0

是的,'onItemSelected()'的位置'參數是'Spinner'中所選項目的位置。這就是爲什麼你需要將'troopPosition'傳遞給'OnItemSelectedListener'並使用它。 –

0

您可以在匿名類移動。

如果您想要當前的ListView元素以及內部適配器位置,您希望獲得兩個位置元素。

有可能是更清潔的方式來做到這一點,但它是第一個想法我有

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