我想使用一个微调器,最初(当用户还没有做出选择时)显示文本“Select One”。当用户单击微调器时,将显示项目列表,用户可以选择其中一个选项。用户做出选择后,所选项目将显示在微调器中,而不是“Select One”。
我有以下代码来创建一个旋转器:
String[] items = new String[] {"One", "Two", "Three"};
Spinner spinner = (Spinner) findViewById(R.id.mySpinner);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, items);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
使用这段代码,最初会显示项目“One”。我可以在项目中添加一个新项目“Select One”,但“Select One”也会作为第一项显示在下拉列表中,这不是我想要的。
我该如何解决这个问题?
我昨天遇到了同样的问题,不想向ArrayAdapter添加隐藏项或使用反射,这工作得很好,但有点脏。
在阅读了许多帖子和尝试之后,我通过扩展ArrayAdapter和覆盖getView方法找到了一个解决方案。
import android.content.Context;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
/**
* A SpinnerAdapter which does not show the value of the initial selection initially,
* but an initialText.
* To use the spinner with initial selection instead call notifyDataSetChanged().
*/
public class SpinnerAdapterWithInitialText<T> extends ArrayAdapter<T> {
private Context context;
private int resource;
private boolean initialTextWasShown = false;
private String initialText = "Please select";
/**
* Constructor
*
* @param context The current context.
* @param resource The resource ID for a layout file containing a TextView to use when
* instantiating views.
* @param objects The objects to represent in the ListView.
*/
public SpinnerAdapterWithInitialText(@NonNull Context context, int resource, @NonNull T[] objects) {
super(context, resource, objects);
this.context = context;
this.resource = resource;
}
/**
* Returns whether the user has selected a spinner item, or if still the initial text is shown.
* @param spinner The spinner the SpinnerAdapterWithInitialText is assigned to.
* @return true if the user has selected a spinner item, false if not.
*/
public boolean selectionMade(Spinner spinner) {
return !((TextView)spinner.getSelectedView()).getText().toString().equals(initialText);
}
/**
* Returns a TextView with the initialText the first time getView is called.
* So the Spinner has an initialText which does not represent the selected item.
* To use the spinner with initial selection instead call notifyDataSetChanged(),
* after assigning the SpinnerAdapterWithInitialText.
*/
@Override
public View getView(int position, View recycle, ViewGroup container) {
if(initialTextWasShown) {
return super.getView(position, recycle, container);
} else {
initialTextWasShown = true;
LayoutInflater inflater = LayoutInflater.from(context);
final View view = inflater.inflate(resource, container, false);
((TextView) view).setText(initialText);
return view;
}
}
}
Android在初始化Spinner时所做的,是在为T[]对象中的所有项目调用getView之前为所选项目调用getView。
SpinnerAdapterWithInitialText在第一次调用时返回带有initialText的TextView。
其他时间都调用super。getView是ArrayAdapter的getView方法如果你正常使用Spinner,它会被调用。
要找出用户是否选择了一个微调项,或者微调器是否仍然显示initialText,请调用selectionMade并移交适配器分配给的微调器。
我最终使用了Button。虽然Button不是旋转器,但其行为很容易自定义。
首先像往常一样创建适配器:
String[] items = new String[] {"One", "Two", "Three"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_dropdown_item, items);
注意,我使用simple_spinner_dropdown_item作为布局id。这将有助于创建一个更好的外观时,创建警报对话框。
在onClick处理我的按钮,我有:
public void onClick(View w) {
new AlertDialog.Builder(this)
.setTitle("the prompt")
.setAdapter(adapter, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO: user specific action
dialog.dismiss();
}
}).create().show();
}
就是这样!
似乎是一个平庸的解决方案,但我通常把简单的TextView在纺纱器的前面。整个Xml是这样的。(嘿,伙计们,别朝我开枪,我知道你们有些人不喜欢这种婚姻):
<FrameLayout
android:id="@+id/selectTypesLinear"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<Spinner
android:id="@+id/spinnerExercises"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:entries="@array/exercise_spinner_entries"
android:prompt="@string/exercise_spinner_prompt"
/>
<TextView
android:id="@+id/spinnerSelectText"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Hey! Select this guy!"
android:gravity="center"
android:background="#FF000000" />
</FrameLayout>
然后我隐藏TextView时,一个项目被选中。显然,TextView的背景颜色应该与旋转器相同。适用于Android 4.0。不知道旧版本。
是的。因为Spinner在开始时调用setOnItemSelectedListener,隐藏textview可能有点棘手,但可以这样做:
Boolean controlTouched;
exerciseSpinner.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
controlTouched = true; // I touched it but but not yet selected an Item.
return false;
}
});
exerciseSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
if (controlTouched) { // Are you sure that I touched it with my fingers and not someone else ?
spinnerSelText.setVisibility(View.GONE);
}
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
}
});
参考上述答案之一:https://stackoverflow.com/a/23005376/1312796
我添加了我的代码来修复一个小错误。哪里没有数据检索..如何显示提示文本..!
这是我的诀窍……我觉得挺好用的。!
试着把你的旋转器在一个relative_layout和对齐的Textview与你的旋转器和发挥Textview的可见性(SHOW/HIDE)每当旋转器的适配器加载或空..像这样:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="20dp"
android:background="#ededed"
android:orientation="vertical">
<TextView
android:id="@+id/txt_prompt_from"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textColor="@color/gray"
android:textSize="16sp"
android:layout_alignStart="@+id/sp_from"
android:text="From"
android:visibility="gone"/>
<Spinner
android:id="@+id/sp_from"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
/>
代码如下:
txt_from = (TextView) rootView.findViewById(R.id.txt_prompt_from);
在转轮适配器加载并为空前后调用此方法。
setPromptTextViewVisibility ();//正确或错误
setPromptTextViewVisibility (boolean visible)
{
如果(可见的)
{
txt_from.setVisibility (View.VISIBLE);
}
其他的
{
txt_from.setVisibility (View.INVISIBLE);
}
}