Android 스피너 위젯에서 하나의 항목을 숨기는 방법을 찾고 있습니다. 이렇게하면 항목을 선택하지 않은 상태에서 스피너를 시뮬레이션 할 수 있으며 선택된 모든 항목에 대해 onItemSelected () 콜백이 항상 호출됩니다 (숨겨진 항목이 “현재”항목 인 경우). 일반적으로 콜백을 생성하지 않는 스피너에는 항상 하나의 항목, 즉 현재 항목이 있습니다.
항목을 비활성화 (회색으로 표시)하는 방법에 대한 일부 코드가 stackoverflow에 있지만 존재하지 않는 것처럼 항목을 완전히 숨기는 방법은 아닙니다.
많은 실험 끝에 다양한 구형 및 신규 Android 플랫폼에서 작동하는 다소 해킹 같은 솔루션을 찾았습니다. 눈에 띄지 않는 사소한 외관상의 단점이 있습니다. “스피너를 사용하지 마십시오”라는 것 외에 더 공식적인 솔루션에 대해 듣고 싶습니다.
이것은 항상 스피너의 첫 번째 항목을 숨기지 만 임의의 항목이나 둘 이상의 항목을 숨기도록 상당히 쉽게 확장 할 수 있습니다. 스피너 항목 목록의 시작 부분에 빈 문자열이 포함 된 더미 항목을 추가합니다. 스피너 대화 상자가 열리기 전에 현재 스피너 선택을 항목 0으로 설정할 수 있습니다. 이렇게하면 선택되지 않은 스피너가 시뮬레이션됩니다.
ArrayAdapter 메서드 재정의를 사용한 Spinner 설정 예 :
List<String> list = new ArrayList<String>();
list.add(""); // Initial dummy entry
list.add("string1");
list.add("string2");
list.add("string3");
// Populate the spinner using a customized ArrayAdapter that hides the first (dummy) entry
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, list) {
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent)
{
View v = null;
// If this is the initial dummy entry, make it hidden
if (position == 0) {
TextView tv = new TextView(getContext());
tv.setHeight(0);
tv.setVisibility(View.GONE);
v = tv;
}
else {
// Pass convertView as null to prevent reuse of special case views
v = super.getDropDownView(position, null, parent);
}
// Hide scroll bar because it appears sometimes unnecessarily, this does not prevent scrolling
parent.setVerticalScrollBarEnabled(false);
return v;
}
};
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mySpinner.setAdapter(dataAdapter);
답변
임의의 항목이나 둘 이상의 항목을 숨기려면 자체 어댑터를 구현하고 숨기려는 인덱스 (또는 인덱스 배열 목록)를 설정할 수 있다고 생각합니다.
public class CustomAdapter extends ArrayAdapter<String> {
private int hidingItemIndex;
public CustomAdapter(Context context, int textViewResourceId, String[] objects, int hidingItemIndex) {
super(context, textViewResourceId, objects);
this.hidingItemIndex = hidingItemIndex;
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
View v = null;
if (position == hidingItemIndex) {
TextView tv = new TextView(getContext());
tv.setVisibility(View.GONE);
v = tv;
} else {
v = super.getDropDownView(position, null, parent);
}
return v;
}
}
그리고 항목 목록을 만들 때 사용자 지정 어댑터를 사용합니다.
List<String> list = new ArrayList<String>();
list.add(""); // Initial dummy entry
list.add("string1");
list.add("string2");
list.add("string3");
int hidingItemIndex = 0;
CustomAdapter dataAdapter = new CustomAdapter(this, android.R.layout.simple_spinner_item, list, hidingItemIndex);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mySpinner.setAdapter(dataAdapter);
(코드를 테스트하지 않았습니다) 도움이되기를 바랍니다.
답변
목록을 잘라서 목록 끝에있는 항목을 숨기는 것이 더 쉽습니다.
그러나 먼저 선택하여 스피너에 표시되도록 한 다음 선택 항목이 표시된 항목 중 하나로 변경되었는지 확인해야합니다.
List<String> list = new ArrayList<String>();
list.add("string1");
list.add("string2");
list.add("string3");
list.add("[Select one]");
final int listsize = list.size() - 1;
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, list) {
@Override
public int getCount() {
return(listsize); // Truncate the list
}
};
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mySpinner.setAdapter(dataAdapter);
mySpinner.setSelection(listsize); // Hidden item to appear in the spinner
답변
스피너 드롭 다운에서 항목을 숨기려면 필요한 기준에 따라 숨겨야하는 항목의 위치를 전달해야합니다. 드롭 다운에서 선택한 항목을 숨기는 사용 사례에서이 작업을 수행했습니다.
public class CustomAdapter extends ArrayAdapter<String> {
private List<String> dates;
private int hideItemPostion;
public CustomAdapter (Context context, int resource, List<String> dates) {
super(context, resource,dates);
this.dates=dates;
}
public void setItemToHide(int itemToHide)
{
this.hideItemPostion =itemToHide;
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
View v = null;
if (position == hideItemPostion) {
TextView tv = new TextView(getContext());
tv.setVisibility(View.GONE);
tv.setHeight(0);
v = tv;
v.setVisibility(View.GONE);
}
else
v = super.getDropDownView(position, null, parent);
return v;
}}
그리고 어댑터 설정은 다음과 같습니다.
final CustomAdapter dataAdapter = new CustomAdapter(this,R.layout.spinner_item,dates);
dataAdapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
spinner.setAdapter(dataAdapter);
dataAdapter.setItemToHide(0);
드롭 다운에서 일부 항목을 선택하면 위치도 변경해야합니다.
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, final int i, long l) {
dataAdapter.notifyDataSetChanged();
mEPGDateSelector.setSelection(i);
dataAdapter.setItemToHide(i);}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
답변
관심을 위해 “프롬프트”를 힌트로 사용하는 솔루션을 만들었습니다. 이 코드는를 위해 만들어 Xamarin.Android
졌지만 10 분 안에 Java로 완벽하게 이식 될 수 있습니다. ArrayAdapter
0 인덱싱 또는 개수 인덱싱 항목을 소스 배열에 추가하지 않고 간단하게 사용하십시오 . SpinnerGeolocation.SelectedItemId
아무것도 선택하지 않은 경우 에도 -1로 설정 됩니다 ( hint
현재 항목 임).
public class ArrayAdapterWithHint<T>: ArrayAdapter<T>
{
protected bool HintIsSet = false;
protected int HintResource = 0;
public ArrayAdapterWithHint(Context context, int textViewResourceId,
T[] objects)
: base(context, textViewResourceId, objects)
{
}
public ArrayAdapterWithHint(Context context, int hintResource,
int textViewResourceId, T[] objects)
: base(context, textViewResourceId, objects)
{
HintResource = hintResource;
}
public ArrayAdapterWithHint(Context context, int textViewResourceId,
IList<T> objects)
: base(context, textViewResourceId, objects)
{
}
public ArrayAdapterWithHint(Context context, int hintResource,
int textViewResourceId, IList<T> objects)
: base(context, textViewResourceId, objects)
{
HintResource = hintResource;
}
public override View GetDropDownView(int position, View convertView,
ViewGroup parent)
{
if (HintIsSet)
return base.GetDropDownView(position + 1,
convertView, parent);
return base.GetDropDownView(position, convertView, parent);
}
public override View GetView(int position, View convertView,
ViewGroup parent)
{
if (!HintIsSet && parent is Spinner &&
!string.IsNullOrWhiteSpace((parent as Spinner).Prompt))
{
Insert((parent as Spinner).Prompt, 0);
HintIsSet = true;
(parent as Spinner).SetSelection(base.Count - 1);
}
if (HintIsSet && position >= base.Count - 1)
{
View hintView = base.GetView(0, convertView, parent);
if (hintView is TextView)
(hintView as TextView).SetTextAppearance(
Context, HintResource);
return hintView;
}
if (HintIsSet && position < base.Count - 1)
return base.GetView(position + 1, convertView, parent);
return base.GetView(position, convertView, parent);
}
public override long GetItemId(int position)
{
if (HintIsSet)
{
if (position >= base.Count - 1)
return -1;
return position;
}
return base.GetItemId(position);
}
public override int Count
{
get
{
return base.Count > 0 && HintIsSet ? base.Count - 1 : base.Count;
}
}
}
답변
내 문제를 해결 한이 솔루션을 찾았습니다.
final Spinner mySpinner = (Spinner)findViewById(R.id.spinner_triptype);
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.spinner_item, R.id.weekofday, triptype_initial);
final ArrayAdapter<String> adapter_temp = new ArrayAdapter<String>
(this,R.layout.spinner_item, R.id.weekofday, triptype_array);
mySpinner.setAdapter(adapter);
mySpinner.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// display your error popup here
if(flag_spinner_isFirst){
mySpinner.setAdapter(adapter_temp);
flag_spinner_isFirst = false;
}
v.onTouchEvent(event);
return true;
}
});
답변
항목이 필터링되면 Spinner에 추가하는 것이 안전하기 때문에 Spinner보다는 Array List에 유효성 검사를 두는 것이 더 낫다고 생각합니다.
답변
나를 위해 가장 잘 작동하는 또 다른 접근 방식은 새로운 빈 뷰 객체를 반환하는 것입니다. 이것은 배열 요소를 가지고 놀지 않기 때문에 상당히 깔끔한 접근 방식입니다.
어댑터 클래스 확장 만들기 ArrayAdapter
당신의 방법 안에
public View getView(int position, View convertView, ViewGroup parent) {
View row = getCustomView();
if(position==0) // put the desired check here.
{
row = new View(context);
}
}
return row;
}