自定义选择框和选择开关

Posted 猫叔聊技术

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义选择框和选择开关相关的知识,希望对你有一定的参考价值。

为了满足越来越好看的界面效果,android内部的控件已经无法满足大量程序员们的需求。那么自定义控件应运而生,下面我们写一个自定义的选择框:

首先activity_down_selected.xml布局文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#22000000" >

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp" >

        <EditText
            android:id="@+id/et"
            android:layout_width="150dp"
            android:layout_height="40dp" />

        <ImageView
            android:id="@+id/iv"
            android:layout_centerVertical="true"
            android:layout_alignRight="@id/et"
            android:src="@android:drawable/ic_menu_add"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </RelativeLayout>

</RelativeLayout>

接着呢就是咱们的代码实现了 DownSelectedActivity.java:

package com.xuhao.downselect;

import java.util.ArrayList;

import android.app.Activity;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;

public class DownSelectedActivity extends Activity implements OnClickListener 
	private EditText et;
	private ImageView iv;
	private ArrayList<String> lists = new ArrayList<String>();
	private int popwindowHeight = 300;
	private ListView listView;
	private MyBaseAdapter adapter;
	private PopupWindow popupWindow;

	@Override
	protected void onCreate(Bundle savedInstanceState) 
		super.onCreate(savedInstanceState);
		initView();
		initListener();
		initData();

	

	private void initView() 
		setContentView(R.layout.activity_down_selected);
		et = (EditText) findViewById(R.id.et);
		iv = (ImageView) findViewById(R.id.iv);

	

	private void initListener() 
		iv.setOnClickListener(this);		
	

	private void initData() 
		for (int i = 0; i < 15; i++) 
			lists.add(90000 + i + "");
		
		initListView();
	

	private void initListView() 
		listView = new ListView(this);
		listView.setBackgroundColor(Color.WHITE);
		listView.setVerticalScrollBarEnabled(false);// 隐藏listview的滚动条
		adapter = new MyBaseAdapter();
		listView.setAdapter(adapter);
		
		listView.setOnItemClickListener(new OnItemClickListener() 

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) 
				et.setText(lists.get(position));
				popupWindow.dismiss();
			
		);
	

	private void showNumberLists() 
		if (popupWindow == null) 
			popupWindow = new PopupWindow(listView, et.getWidth(),
					popwindowHeight);
		

		popupWindow.setFocusable(true);
		popupWindow.setBackgroundDrawable(new BitmapDrawable());
		popupWindow.setOutsideTouchable(true);
		popupWindow.showAsDropDown(et, 0, 0);
	

	@Override
	public void onClick(View v) 
		switch (v.getId()) 
		case R.id.iv:
			showNumberLists();
			break;
		
	

	class MyBaseAdapter extends BaseAdapter 

		@Override
		public int getCount() 
			return lists.size();
		

		@Override
		public View getView(final int position, View convertView,
				ViewGroup parent) 
			final View view = View.inflate(DownSelectedActivity.this,
					R.layout.adapter_item, null);
			TextView tv = (TextView) view.findViewById(R.id.tv);
			ImageButton ivs = (ImageButton) view.findViewById(R.id.iv);
			tv.setText(lists.get(position));
			ivs.setOnClickListener(new OnClickListener() 

				@Override
				public void onClick(View v) 
					lists.remove(position);
					notifyDataSetChanged();

					int listviewHeight = lists.size() * view.getHeight();
					popupWindow.update(et.getWidth(),
							listviewHeight > popwindowHeight ? popwindowHeight
									: listviewHeight);

					if (lists.size() == 0) 
						popupWindow.dismiss();
						iv.setVisibility(View.GONE);
					
				
			);
			return view;
		

		@Override
		public Object getItem(int position) 
			return lists.get(position);
		

		@Override
		public long getItemId(int position) 
			return position;
		

	


那么咱们还需要一个显示下拉信息的布局文件adapter_item.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="wrap_content"
    android:gravity="center_vertical"
    android:padding="5dp"
    android:descendantFocusability="blocksDescendants"
    android:orientation="horizontal" >
<!-- 如果listview中存在button,checedbox等可以获得焦点的空间需要加上这一句 特么才能点击出效果  android:descendantFocusability="blocksDescendants"-->
    <TextView
        android:id="@+id/tv"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:paddingRight="10dp"
        android:drawableLeft="@android:drawable/ic_btn_speak_now"
        android:gravity="center_vertical"
        android:text="90000" />

    <ImageButton
        android:id="@+id/iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@android:drawable/ic_delete" />

</LinearLayout>
最后效果就实现了:

点击之后文字进入编辑框(哈哈,有点丑)

下面的是开关选择,自己用ps做了个图片大家不要介意

首先还是布局文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >


    <com.xuhao.downselect.view.ToggledSelectedView
        android:id="@+id/tsv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        android:layout_centerInParent="true">
    </com.xuhao.downselect.view.ToggledSelectedView>


</RelativeLayout>
表着急接着就是自定义的view:

package com.xuhao.downselect.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

/**
 * 自定义开关
 * 
 * @author json
 * 
 */
public class ToggledSelectedView extends View 
	private ToggleState toggleState = ToggleState.Open;// 开关状态
	private Bitmap sildeBg;
	private Bitmap switchBg;
	private int currentX;
	private boolean silding = false;

	// 如果view想要在java代码中动态创建,走这个方法
	public ToggledSelectedView(Context context) 
		super(context);
	

	// 如果是在布局中使用只需要重写这个狗仔方法
	public ToggledSelectedView(Context context, AttributeSet attrs) 
		super(context, attrs);
	

	public enum ToggleState 
		Open, Close;
	

	/**
	 * 设置滑动背景
	 * 
	 * @param on
	 */
	public void setSildeBackgroundResource(int sildeBackground) 
		sildeBg = BitmapFactory.decodeResource(getResources(), sildeBackground);
	

	/**
	 * 设置滑动块背景
	 * 
	 * @param off
	 */
	public void setSwitchBackgroundResource(int switchBackground) 
		switchBg = BitmapFactory.decodeResource(getResources(),
				switchBackground);
	

	/**
	 * 设置开关状态
	 * 
	 * @param open
	 */
	public void setToggleState(ToggleState state) 
		toggleState = state;
	

	/**
	 * 1.测量
	 */
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		setMeasuredDimension(sildeBg.getWidth(), sildeBg.getHeight());

	

	/**
	 * 3.绘制
	 */
	@Override
	protected void onDraw(Canvas canvas) 
		super.onDraw(canvas);
		// 1.绘制背景图片
		canvas.drawBitmap(sildeBg, 0, 0, null);
		// 2.绘制开关
		if (silding) 
			int left = currentX - switchBg.getWidth() / 2;
			if (left < 0)
				left = 0;
			if (left > sildeBg.getWidth() - switchBg.getWidth()) 
				left = sildeBg.getWidth() - switchBg.getWidth();
			
			canvas.drawBitmap(switchBg, left, 0, null);
		 else 

			if (toggleState == ToggleState.Open) 
				canvas.drawBitmap(switchBg,
						sildeBg.getWidth() - switchBg.getWidth(), 0, null);
			 else 
				canvas.drawBitmap(switchBg, 0, 0, null);
			

		

	

	@Override
	public boolean onTouchEvent(MotionEvent event) 
		currentX = (int) event.getX();
		switch (event.getAction()) 
		case MotionEvent.ACTION_DOWN:
			silding = true;
			break;
		case MotionEvent.ACTION_MOVE:
			break;
		case MotionEvent.ACTION_UP:
			silding = false;
			int centerX = sildeBg.getWidth() / 2;
			if (currentX > centerX) 
				if (toggleState != ToggleState.Open) 
					toggleState = ToggleState.Open;
					if (buttonStateListener != null) 
						buttonStateListener
								.setOnToggleButtonChange(toggleState);
					
				

			 else 
				if (toggleState != ToggleState.Close) 
					toggleState = ToggleState.Close;
					if (buttonStateListener != null) 
						buttonStateListener
								.setOnToggleButtonChange(toggleState);
					
				

			
			break;
		
		invalidate();
		return true;
	

	private OnToggleButtonStateListener buttonStateListener;

	public void setOnToggleButtonChangeListener(
			OnToggleButtonStateListener buttonStateListener) 
		this.buttonStateListener = buttonStateListener;
	;

	// 通过自定义接口把数据传递给调用者类似于观察者模式
	public interface OnToggleButtonStateListener 
		void setOnToggleButtonChange(ToggleState state);
	



接着就是代码了:

package com.xuhao.downselect;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;

import com.xuhao.downselect.view.ToggledSelectedView;
import com.xuhao.downselect.view.ToggledSelectedView.OnToggleButtonStateListener;
import com.xuhao.downselect.view.ToggledSelectedView.ToggleState;

public class MainActivity extends Activity 
	private ToggledSelectedView tsv;

	@Override
	protected void onCreate(Bundle savedInstanceState) 
		super.onCreate(savedInstanceState);
		initView();
		initData();
	

	private void initView() 
		setContentView(R.layout.activity_main);
		tsv = (ToggledSelectedView) findViewById(R.id.tsv);
	

	private void initData() 
		tsv.setSildeBackgroundResource(R.drawable.on);
		tsv.setSwitchBackgroundResource(R.drawable.off);
		tsv.setToggleState(ToggleState.Open);
		tsv.setOnToggleButtonChangeListener(new OnToggleButtonStateListener() 

			@Override
			public void setOnToggleButtonChange(ToggleState state) 
				Toast.makeText(MainActivity.this,
						state == ToggleState.Open ? "开启" : "关闭",
						Toast.LENGTH_SHORT).show();
				if(state == ToggleState.Open)
					MainActivity.this.startActivity(new Intent(MainActivity.this,DownSelectedActivity.class));
				
			
		);
	




项目下载地址:https://github.com/xh2015/downselect-switch.git

以上是关于自定义选择框和选择开关的主要内容,如果未能解决你的问题,请参考以下文章

安卓自定义弧形刻度选择器

如何在选择器中传递自定义 UITableViewCell

如何显示自定义警报以在 ios 中启用通知

具有自定义比例的图片中的点选择

如何在qqis中快速利用自定义坐标定位,进行准确测量

[Ubuntu]18自定义切换输入法的快捷键