2016-06-15 2 views
2

앱의 간단한 설정 페이지를 만들려고합니다.Spinner를 ListView에 동적으로 추가했을 때 Spinner에서 선택한 항목에 어떻게 액세스합니까?

XML 파일에서 레이아웃을 정의한 객체 목록을 만들고 싶습니다.

이러한 개체의 레이아웃에는 제목 TextView, 도움말 TextView 및 회 전자가 있습니다.

코드에서 이러한 개체를 동적으로 추가 할 때 선택한 값을 얻을 수 있도록 이러한 개별 Spinner보기를 어떻게 참조합니까?

나는 현재 설정 개체 (목록이 채워집니다 무엇을)이

:

public class Setting { 

    private String name; 
    private String description; 
    private String[] values; 

    public Setting(String name, String description, String[] values) { 
     this.name = name; 
     this.description = description; 
     this.values = values; 
    } 

    public String getName() { 
     return name; 
    } 

    public String getDescription() { 
     return description; 
    } 

    public String[] getValues() { 
     return values; 
    } 
} 

사용자 정의 ArrayAdapter와는 뷰 개체를 설정 번역 :

을 (R.layout.spinner_row_text_layout.xml입니다 단지 텍스트보기 ... 스피너의 항목의 레이아웃)

public class SettingsAdapter extends ArrayAdapter<Setting> { 

    public SettingsAdapter(Context context, ArrayList<Setting> settings) { 
     super(context, 0, settings); 
    } 

    @Override 
    // Takes the position in the array, the view to convert, and the parent of the view as parameters 
    public View getView(int position, View convertView, ViewGroup parent) { 

     // Get the item in this position 
     Setting setting = getItem(position); 

     // Check if a view is being reused, otherwise inflate the view (look at view recycling in lists) 
     if (convertView == null) { 
      convertView = LayoutInflater.from(getContext()).inflate(R.layout.settings_row_view, parent, false); 
     } 

     // findViewById in the given view to convert 
     TextView title = (TextView) convertView.findViewById(R.id.titleText); 
     TextView help = (TextView) convertView.findViewById(R.id.helpText); 
     Spinner spinner = (Spinner) convertView.findViewById(R.id.spinner); 

     ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(getContext(), R.layout.spinner_row_text_layout, setting.getValues()); 
     spinner.setAdapter(spinnerAdapter); 

     title.setText(setting.getName()); 
     help.setText(setting.getDescription()); 

     return convertView; 
    } 
} 

그리고 다음 레이아웃 파일을 정의

설정 페이지 레이아웃 : 각 ListView에 항목에 대한

<RelativeLayout 

    android:id="@+id/relativeLayout" 
    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" 
    tools:context="com.example.cgillions.counter.SettingsActivity"> 

    <ListView 
     android:id="@+id/settingsList" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:choiceMode="singleChoice" 
     android:divider="@color/black" 
     android:dividerHeight="5dp"/> 

</RelativeLayout> 

레이아웃 :

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="horizontal" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"> 

    <LinearLayout 
     android:orientation="vertical" 
     android:layout_width="0dp" 
     android:layout_height="wrap_content" 
     android:layout_weight="1"> 

     <TextView 
      android:id="@+id/titleText" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 

      android:text="Hello" 
      android:textSize="20sp" 
      android:textColor="@color/black" 

      android:gravity="center_vertical"/> 

     <TextView 
      android:id="@+id/helpText" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 

      android:text="@string/animation_settings_hint" 
      android:textSize="12sp" 
      /> 

    </LinearLayout> 

    <Spinner 
     android:id="@+id/spinner" 
     android:layout_width="0dp" 
     android:layout_height="wrap_content" 
     android:layout_weight="1.5"/> 

</LinearLayout> 

나는 설정 페이지 레이아웃에 해당하는 활동을 시작할 때, 나는 다음과 같은 오류 얻을 :

을 junit.framework.Assert.assertNotNull (Assert.java:211)

at com.example.cgillions.counter.SettingsActivity.

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    setContentView(R.layout.activity_settings); 

    setTitle("Settings"); 

    // Create a new Setting object in order to populate list 
    animSetting = new Setting("Animation", getResources().getString(R.string.animation_settings_hint), getResources().getStringArray(R.array.anim_values)); 

    settings = new ArrayList<>(); 
    settings.add(animSetting); 

    ListView settingsList = (ListView) findViewById(R.id.settingsList); 
    assertNotNull(settingsList); 
    settingsList.setAdapter(new SettingsAdapter(this, settings)); 

    animSpinner = (Spinner) settingsList.findViewById(R.id.spinner); 
    assertNotNull(animSpinner); 
} 

오류가 발생에서 onCreate android.app.Activity.performCreate (Activity.java:5990)에서 (SettingsActivity.java:46)

이 내에서 onCreate() 메소드입니다 마지막 줄 - 예. ID '회 전자'가있는보기를 찾을 수 없으므로 null입니다. Spinner에 잘못 액세스하고 있습니다. 어떻게해야하는지 조언 할 수 있습니까?

선택한 항목을 가져 오기 위해 Spinner 개체를 가져 오려고합니다.

+0

R.idspinner는 목록보기 내부의 레이아웃이 아니지만 내부보기의 레이아웃이며 모든 행에는 Spinner의 새 인스턴스가 있습니다. 왜 활동에 스피너가 필요합니까? (어떤 행? 첫 행의 행? 두 번째 행?) – CLucera

+0

'내부 뷰의 레이아웃입니까?'라는 것은 무엇을 의미합니까? 새 인스턴스가있는 각 행에 대해 말하는 것을 알고 있습니다. 각 개별 목록 항목에 어떻게 액세스합니까? 이 경우 첫 번째 항목의 회 전자가 필요합니다 (목록에 하나의 설정 만있는 경우 ...) – Charlie

+0

나는 선택한 항목을 가져 와서 다른 활동에 대한 동작을 변경할 수 있도록 활동의 회 전자를 원했습니다. – Charlie

답변

2

시도해 볼만한 것. 당신의 설정 인스턴스에 스피너를, 당신의 getView() 메소드에서, 그리고

public class Setting { 

    private String name; 
    private String description; 
    private String[] values; 
    private Spinner spinner; 

    public Setting(String name, String description, String[] values) { 
     this.name = name; 
     this.description = description; 
     this.values = values; 
    } 

    public String getName() { 
     return name; 
    } 

    public String getDescription() { 
     return description; 
    } 

    public String[] getValues() { 
     return values; 
    } 

    public void setSpinner(Spinner s) { 
     spinner = s; 
    } 

    public Spinner getSpinner() { 
     return spinner; 
    } 
} 

을 제공합니다 : 당신의 설정 클래스에 스피너 인스턴스를 추가

ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(getContext(), R.layout.spinner_row_text_layout, setting.getValues()); 
spinner.setAdapter(spinnerAdapter); 
if (setting.getSpinner() == null) { 
    setting.setSpinner(spinner); 
} 

을 그런 다음 설정의 목록에 액세스 할 수 있습니다 가정 , 각각 연관된 스피너에 액세스 할 수 있습니다. null 스피너가있는 Setting을 찾으면 Activity에서 뷰를 보지 못했고, 사용자가 변경하지 않았 음을 의미합니다. 그러나 그것이 정말로 당신이 원하는 것이 었는지 나는 모른다.

이렇게하면 각 설정에 대해 스피너에 액세스 할 수 있지만 사용자의 선택을 저장하거나 선택한 항목을 회 전자에 설정하는 논리가 없습니다. 즉, 회 전자에 옵션 A, B 및 C가 있고 사용자가 B를 선택한 경우 이제 B를 읽을 수 있지만 저장할 장소가 없습니다. Setting 클래스에는 선택한 값을 유지하는 필드가 있어야합니다. 그리고 getView() 메소드는 B를 현재 값으로 표시하도록 알려주기 위해 spinner.setSelection()을 호출해야합니다. 그렇지 않으면 이전에 사용자가 선택한 것과 상관없이 항상 A가 표시됩니다.

+0

나는이 해결책을 좋아한다. 각 설정에 Spinner가있는 것이 좋습니다. 그러나 각 스피너의 값을 읽으려고하면 모두 동일한 값 (* 마지막 * Setting 's Spinner의 값이 목록에 추가됨)을 갖습니다. – Charlie

+0

현재 애니메이션과 배경은 2 개입니다. 다음 줄은 입니다. System.out.println (settings.get (0) .getName()); System.out.println (settings.get (0) .getSpinner(). getSelectedItem(). toString()); System.out.println (settings.get (1) .getName()); System.out.println (settings.get (1) .getSpinner(). getSelectedItem(). toString()); 애니메이션 인쇄 \ n 흰색 \ n 배경 \ n 흰색 – Charlie

+0

아직 해결 했습니까? 그렇지 않다면, 내가 시도 할 다음 것은 ListView에서'onItemClick()'의 테스트를 설정하는 것이다. 세 번째 인수는 ListView에서 클릭 한 행 (0에서 시작)을 제공하는 int pos입니다. 회 전자에서 항목을 선택할 때'settingsList.onItemClick()'이벤트가 발생하는지 확인하십시오. 그렇게 할 경우, 스피너에 선택된 값을'settingsList.onItemClick()'이벤트와 관련된 Settings 인스턴스에 저장하십시오. –

관련 문제