最近在項(xiàng)目中使用android原生的Spinner發(fā)現(xiàn)其顯示效果沒有想象中的好耕赘,于是就動手寫了一個popuwindow的彈出框下拉列表名斟,在popuwindow中主要使用了ListView自帶的單選和多選模式跃巡。
listview中使用自帶的選擇框有兩種方式败明,第一種方式:
ListView lv = (ListView) findViewById(R.id.list_view);
lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
第二中方式:就是在listview布局中直接加液茎,建議使用第二種
android:choiceMode="singleChoice"
先書寫一個帶listview的布局歌殃,popuwindow_spinner布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@mipmap/spinner_pop_bg">
<TextView
android:id="@+id/pop_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="6dp"
android:gravity="center"
android:textSize="@dimen/title_size"/>
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/grey_line"/>
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#00000000"
android:choiceMode="singleChoice"
>
</ListView>
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/grey_line"/>
<TextView
android:id="@+id/pop_cancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="6dp"
android:text="@string/cancel"
android:textColor="@color/orange"
android:gravity="center"
android:textSize="@dimen/title_size"/>
</LinearLayout>
其實(shí)在popuwindow中使用listview和在Activity中使用相同乔妈,具體實(shí)現(xiàn)代碼如下(具體使用看注釋):
public class SpinnerPopuwindow extends PopupWindow{
private View conentView;
private ListView listView;
private SpinnerPopAdapter adapter;
private Activity context;
private TextView pop_title;
private TextView pop_cancel;
/**
* @param context 上下文
* @param string 獲取到未打開列表時(shí)顯示的值
* @param list 需要顯示的列表的集合
* @param itemsOnClick listview在activity中的點(diǎn)擊監(jiān)聽事件
*/
@SuppressLint("InflateParams")
public SpinnerPopuwindow(final Activity context, final String string, final List<String> list, AdapterView.OnItemClickListener itemsOnClick) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.context =context;
conentView = inflater.inflate(R.layout.popuwindow_spinner, null);
// 設(shè)置SelectPicPopupWindow的View
this.setContentView(conentView);
// 設(shè)置SelectPicPopupWindow彈出窗體的寬
this.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
// this.setWidth(view.getWidth());
// 設(shè)置SelectPicPopupWindow彈出窗體的高
this.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
// 設(shè)置SelectPicPopupWindow彈出窗體可點(diǎn)擊
this.setFocusable(true);
// 刷新狀態(tài)
this.update();
this.setOutsideTouchable(false);
// 實(shí)例化一個ColorDrawable顏色為半透明
ColorDrawable dw = new ColorDrawable(0000000000);
// 點(diǎn)back鍵和其他地方使其消失,設(shè)置了這個才能觸發(fā)OnDismisslistener ,設(shè)置其他控件變化等操作
this.setBackgroundDrawable(dw);
this.setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss() {
darkenBackground(1f);
}
});
//解決軟鍵盤擋住彈窗問題
this.setSoftInputMode(PopupWindow.INPUT_METHOD_NEEDED);
this.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
// 設(shè)置SelectPicPopupWindow彈出窗體動畫效果
// this.setAnimationStyle(R.style.AnimationPreview);
adapter = new SpinnerPopAdapter(context,list);
listView = (ListView) conentView.findViewById(R.id.listView);
listView.setOnItemClickListener(itemsOnClick);
listView.setAdapter(adapter);
// setAdapter是異步進(jìn)行的氓皱,為了使彈窗能即時(shí)刷新路召,所以使用post+Runnable
listView.post(new Runnable() {
@Override
public void run() {
//主要是為了比對未打開列表時(shí)顯示的值和列表中的值進(jìn)行默認(rèn)選中
for(int j = 0;j<list.size();j++){
if(string.equals(list.get(j).toString())){
listView.setItemChecked(j, true);//listview自帶的方法
}else {
listView.setItemChecked(j, false);
}
}
}
});
pop_title = (TextView) conentView.findViewById(R.id.pop_title);
pop_cancel = (TextView) conentView.findViewById(R.id.pop_cancel);
pop_cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
darkenBackground(1f);
}
});
}
//給下拉列表的設(shè)置標(biāo)題,增加復(fù)用性
public void setTitleText(String str){
pop_title.setText(str);
}
//獲取選中列表中的數(shù)據(jù)所對應(yīng)的position
public int getText(){
return listView.getCheckedItemPosition();
}
/**
* 顯示popupWindow
*
* @param parent
*/
public void showPopupWindow(View parent) {
if (!this.isShowing()) {
// 以下拉方式顯示popupwindow
// this.showAsDropDown(parent);
// this.showAsDropDown(parent,0,10);
this.showAtLocation(parent, Gravity.BOTTOM|Gravity.CENTER, 0, 0);
darkenBackground(0.9f);//彈出時(shí)讓頁面背景回復(fù)給原來的顏色降低透明度波材,讓背景看起來變成灰色
}
}
/**
* 關(guān)閉popupWindow
*/
public void dismissPopupWindow() {
this.dismiss();
darkenBackground(1f);//關(guān)閉時(shí)讓頁面背景回復(fù)為原來的顏色
}
/**
* 改變背景顏色股淡,主要是在PopupWindow彈出時(shí)背景變化,通過透明度設(shè)置
*/
private void darkenBackground(Float bgcolor){
WindowManager.LayoutParams lp = context.getWindow().getAttributes();
lp.alpha = bgcolor;
context.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
context.getWindow().setAttributes(lp);
}
}
SpinnerPopAdapter書寫方式是最基本的適配器寫法:
public class SpinnerPopAdapter extends BaseAdapter {
private List<String> content;
private Context context;
private LayoutInflater mInflater;
public SpinnerPopAdapter(Context context,List<String> content){
this.context = context;
this.content = content;
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return content == null ? 0 : content.size();
}
@Override
public Object getItem(int position) {
return content.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if(convertView == null){
convertView = mInflater.inflate(R.layout.popuwindow_spinner_item,null);
viewHolder = new ViewHolder();
viewHolder.tv_spinner = (TextView) convertView.findViewById(R.id.tv_spinner);
viewHolder.check = (CheckableLayout) convertView.findViewById(R.id.check);
convertView.setTag(viewHolder);
}else {
viewHolder = (ViewHolder) convertView.getTag();
}
String spinnerText = content.get(position);
viewHolder.tv_spinner.setText(spinnerText);
return convertView;
}
public static class ViewHolder{
TextView tv_spinner;
public CheckableLayout check;
}
}
adapter中布局各聘,其中要記得自定義選中布局CheckableLayout繼承自RelativeLayout并實(shí)現(xiàn)Checkable揣非,網(wǎng)上例子很多我就不在這兒寫了,popuwindow_spinner_item布局:
<?xml version="1.0" encoding="utf-8"?>
<com.goldenlink.credit.view.CheckableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
android:duplicateParentState="true"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="30dp"
android:gravity="center"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:duplicateParentState="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="20dp"
android:src="@drawable/singlechoice_selector"/>
</com.goldenlink.credit.view.CheckableLayout>
最主要的是在Activity中的使用
public class NewTaskActivity extends Activity implements View.OnClickListener{
public static final String TAG = "NewTaskActivity";
private ImageView goback;
private LinearLayout task_type;
private TextView tv_type;
private SpinnerPopuwindow mSpinnerPopuwindow;
/** 模擬的假數(shù)據(jù) */
private List<String> testData;
private String type;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_newtask);
initView();
}
public void initView(){
goback = (ImageView) findViewById(R.id.goback);
goback.setOnClickListener(this);
task_type = (LinearLayout) findViewById(R.id.task_type);
task_type.setOnClickListener(this);
tv_type = (TextView) findViewById(R.id.tv_type);
TestData();
}
/**
* 模擬假數(shù)據(jù)
*/
private void TestData() {
testData = new ArrayList<>();
for (int i = 0; i < 3; i++) {
String str = new String("數(shù)據(jù)" + i);
testData.add(str);
}
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.goback:
this.finish();
break;
case R.id.task_type:
type = tv_type.getText().toString();
mSpinnerPopuwindow = new SpinnerPopuwindow(this,type,testData,itemsOnClick);
mSpinnerPopuwindow.showPopupWindow(task_type);
mSpinnerPopuwindow.setTitleText("類型");//給下拉列表設(shè)置標(biāo)題
break;
}
}
//SchedulePopuwindow為彈出窗口實(shí)現(xiàn)監(jiān)聽類
private AdapterView.OnItemClickListener itemsOnClick = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String value = testData.get(mSpinnerPopuwindow.getText());
tv_type.setText(value);
mSpinnerPopuwindow.dismissPopupWindow();
}
};
}
Activity中的布局躲因,activity_newtask布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="@dimen/title_height"
android:background="@mipmap/title_bg" >
<ImageView
android:id="@+id/goback"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_centerInParent="true"
android:layout_marginLeft="10dp"
android:src="@mipmap/goback" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/new_task"
android:textColor="@color/white"
android:textSize="@dimen/title_size" />
</RelativeLayout>
<LinearLayout
android:id="@+id/ll_type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:layout_gravity="center"
android:background="@color/white"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
android:textSize="16sp"
android:text="類型"/>
<LinearLayout
android:id="@+id/task_type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="8dp"
android:text="請選擇類型"
android:textSize="14sp"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|right"
android:padding="8dp"
android:src="@mipmap/spinner"
/>
</LinearLayout>
</LinearLayout>
</LinearLayout>