您的位置:首页 > 其它

使用RelativeLayout实现自定义下拉列表Spinner

2015-10-07 16:24 435 查看
Android有提供Spinner,但并不是什么时候都可以满足需求。我们可以通过ReLativeLayout+TextView+ImageView来实现我们自己的一个Spinner,可以完成一些复杂的功能,而且更灵活。

现在进入正题:

先来看一下效果



下面开始具体的实现,作为一个demo,我只写一些核心的代码

首先我们把XML文件先写好。定义一个ListView作为我们显示的下拉列表。我们建一个XML,叫myspinner_list.xml,里面只需放一个ListView即可。

myspinner_list.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout   xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#ffffffff">
<ListView
android:id="@+id/lv_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:divider="#ffffff"
android:dividerHeight="0dp"/>
</LinearLayout>


有了ListView,那我们还需要写ListView里面的Item的XML文件,新建myspinner_list_item.xml,我们的demo比较简单里面就一个TextView。

myspinner_list_item.xml

<TextView
android:id="@+id/tv_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:text="item"
android:padding="10dp"
android:textSize="17sp"
android:background="#ffffff"/>


最后在actitity_main.xml,写好我们的下拉列表的样式,具体的样式就根据项目要求去写
4000
就好了。

actitity_main.xml

<RelativeLayout
android:id="@+id/rl_spinner"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:background="@drawable/relayout_spinner_bg">

<TextView
android:id="@+id/tv_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:textSize="18sp"
android:singleLine="true"/>

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="@drawable/invert_triangle"/>
</RelativeLayout>


到这里我们XML文件就都写好了,我们开始java代码的编写

首先我们需要写一个适配器,我们定义为SpinnerListAdapter.java,继承BaseAdapter

适配器的作用主要是给list_item进行赋值

SpinnerListAdapter.java

public class SpinnerListAdapter extends BaseAdapter {

private int mPosition;
private String[] mItems;
private MySpinner mSpinner;
private Activity mActivity;
private onItemClickListener mListener;

public SpinnerListAdapter(MySpinner spinner, Activity activity, String[] items){
this.mActivity=activity;
this.mItems=items;
this.mSpinner =spinner;
}

public int getCount() {
return mItems.length;
}

public Object getItem(int position) {
return null;
}

public long getItemId(int position) {
return 0;
}

private class ViewHolder {
public TextView text;
}

public View getView(final int arg0, final View arg1, ViewGroup arg2) {
//获取设置好的listener
mListener= mSpinner.getListener();
View view=arg1;
ViewHolder holder=null;
if(view==null){
view= View.inflate(mActivity, R.layout.myspinner_list_item, null);
holder = new ViewHolder();
holder.text=(TextView) view.findViewById(R.id.tv_text);
view.setTag(holder);
}else {
holder = (ViewHolder) view.getTag();
}
holder.text.setText(mItems[arg0]);

view.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mPosition=arg0;
mSpinner.close();
mListener.click(mPosition,arg1);
}
});
return view;
}

//回调接口
public interface onItemClickListener{
public void click(int position, View view);
}
}


然后来到我们最重要的一个类,我们定义为MySpinner.java,继承PopupWindow,PopupWindow其实也是对话框,与AlertDialog不一样的是PopupWindow在界面任何地方显示,像悬浮窗体,具体自行Google,我就不啰嗦了。

MySpinner.java

public class MySpinner extends PopupWindow implements OnItemClickListener {

private String[] mItems;
private MySpinner mWindow;
private SpinnerListAdapter.onItemClickListener mListener;

public MySpinner(Context context, AttributeSet attrs) {
super(context, attrs);
}

public MySpinner(Activity activity, int width, String[] items){
LayoutInflater inflater=activity.getLayoutInflater();
View contentView=inflater.inflate(R.layout.myspinner_list, null);
// 设置PopupWindow的View
this.setContentView(contentView);
// 设置PopupWindow弹出窗体的宽
this.setWidth(width);
// 设置PopupWindow弹出窗体的高
this.setHeight(android.view.WindowManager.LayoutParams.WRAP_CONTENT);
this.setFocusable(true);
this.setOutsideTouchable(true);
// 刷新状态
this.update();
// 实例化一个ColorDrawable颜色
ColorDrawable dw = new ColorDrawable(0xffffffff);
this.setBackgroundDrawable(dw);

this.mItems=items;
ListView listView=(ListView) contentView.findViewById(R.id.lv_list);
mWindow=this;
SpinnerListAdapter adapter=new SpinnerListAdapter(mWindow,activity, mItems);
listView.setAdapter(adapter);
listView.setOnItemClickListener(this);
}

public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
MySpinner.this.dismiss();
}

public void showAtLocation(View parent, int gravity, int x, int y) {
super.showAtLocation(parent, gravity, x, y);
}

public void close(){
this.dismiss();
}

public int position(){
return 0;
}

public void setOnItemClickListener(SpinnerListAdapter.onItemClickListener listener){
this.mListener=listener;
}

public SpinnerListAdapter.onItemClickListener getListener(){
//可以通过this的实例来获取设置好的listener
return mListener;
}
}


其实也没多少东西,上面也有相应的注释。

准备工作已经做完了,我们来调用上面的方法,实现我们的目的

我们在MainActivity进行调用,我们需要监听rl_spinner的点击事件,设置显示的数据源,当选择item时,将数据源的值赋给tv_conten进行显示。

MainActivity .java

public class MainActivity extends AppCompatActivity {

private RelativeLayout rl_spinner;
private TextView tv_content;
private String array[];

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

rl_spinner = (RelativeLayout) findViewById(R.id.rl_spinner);
tv_content = (TextView) findViewById(R.id.tv_content);

//初始化
array = new String[]{"item1", "item2", "item3", "item4", "item5", "item6"};
tv_content.setText(array[0]);

rl_spinner.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MySpinner mySpinner = new MySpinner(MainActivity.this, rl_spinner.getWidth(), array);
mySpinner.showAsDropDown(rl_spinner, 0, 0);//显示在rl_spinner的下方
mySpinner.setOnItemClickListener(new SpinnerListAdapter.onItemClickListener() {
@Override
public void click(int position, View view) {
tv_content.setText(array[position]);
}
});
}
});

}
}


这里是作为一个简单demo,通过这种方法我们可以实现更多更丰富的功能,比如在ListView里可以显示图片,比Spinner会更灵活一点,更多的用法可以自己进行研究。

最后附上源码

源码 http://pan.baidu.com/s/1c0jW2cC
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: