1. 程式人生 > >自定義Spinner--可以預設不選中,修改預設顯示的spinner

自定義Spinner--可以預設不選中,修改預設顯示的spinner

今天接了一個需求,要寫一個下拉框供客戶選擇

但是預設是不選中的,還要有一個提示客戶選擇的內容

一開始覺得挺簡單的,用一個spinner就搞定了,但是發現spinner是預設選中的,而且進入頁面時候就呼叫了onItemSelected這個介面,並且不能修改預設顯示的內容

上網查了一大堆資料,都沒有一個完美的解決方案,都是說什麼在監聽事件里加一個boolean變數,如果點選就變成true,執行需要執行的程式碼

但是這個方法真的很挫!首先,你已經預設選擇了點選第一項,只是你把內容改了,再點選第一項是不執行程式碼了,就說你一定要點第一項以外的Item,才能再去點選第一項

這點就是無法容忍的。

然後只能自己重寫一個了。

思路是重寫一個TextView,然後點選彈出一個PopupWindow。

首先讓我們來看一下控制元件:

public class MySpinner extends TextView{
	private Context mContext;
	private ArrayAdapter adapter;
	private ListView popContentView;
	private OnItemClickListener onItemClickListener;
	private PopupWindow mDropView;
	
	public MySpinner(Context context, AttributeSet attrs) {
		super(context, attrs);
		mContext = context;
	}
	
	@Override
	protected void onFinishInflate() {
		super.onFinishInflate();
		LayoutInflater inflater = LayoutInflater.from(mContext);
		LinearLayout container = (LinearLayout) inflater.inflate(R.layout.spinner_content, null);
		popContentView = (ListView) container.findViewById(R.id.spinner_content);
		mDropView = new PopupWindow(container, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
		mDropView.setBackgroundDrawable(new BitmapDrawable());
		mDropView.setFocusable(true);
		mDropView.setOutsideTouchable(true);
		mDropView.setOutsideTouchable(true);
		mDropView.setTouchable(true);
		container.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				dismissPop();
			}
		});
		this.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mDropView.isShowing()){
					dismissPop();
				}else{
					showPop();
				}
			}
		});
		mDropView.update();
	}
	
	public void setHint(String hint){
		this.setText(hint);
	}
	
	public void setAdapter(ArrayAdapter adapter){
		if(adapter != null){
			this.adapter = adapter;
			popContentView.setAdapter(this.adapter);
		}
		
	}
	
	public void setOnItemSelectedListener(OnItemClickListener listener){
		if(listener != null){
			this.onItemClickListener = listener;
			popContentView.setOnItemClickListener(listener);
		}
		
	}
	
	public void dismissPop(){
		if(mDropView.isShowing()){
			mDropView.dismiss();
		}
	}
	
	public void showPop(){
		mDropView.showAsDropDown(this);
	}

}
很簡單,就是繼承一個TextView,然後點選就彈出一個PopupWindow,PopupWindow的內容是一個ListView。

值得注意的是popupWindow需要攔截返回事件,把自己給dismiss了。

然後就是呼叫了

public class MainActivity extends Activity {
	private static final String[] data = {"我是程式設計師", "所以我愛寫程式碼", "但是有時候寫程式碼也挺累的", "所以無聊時候寫個部落格"};
	
	private MySpinner mSpinner;
	private ArrayAdapter<String> mAdapter;
	private Activity mActivity;
	private int mSelectedPosition = -1;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mActivity= this;
		mSpinner = (MySpinner) findViewById(R.id.my_spinner);
		mAdapter = new ArrayAdapter<String>(this, R.layout.spinner_item, data);
		mSpinner.setAdapter(mAdapter);
		mSpinner.setOnItemSelectedListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				mSpinner.dissmissPop();
<span style="white-space:pre">				</span>mSpinner.setHint(data[position]);
<span style="white-space:pre">				</span>Toast.makeText(mActivity, "我被點選了" + position, Toast.LENGTH_LONG).show();
<span style="white-space:pre">				</span>mSelectedPosition = position;
			}
		});
				
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		if(mSelectedPosition == -1){
			mSpinner.setHint("預設未選中!");
		}else{
			mSpinner.setHint(data[mSelectedPosition]);
		}
	}

}


最後我們來看下效果

好了 這就達到我們要的效果了

最後吐槽下Spinner,竟然不能預設不選中和修改預設顯示內容!