基于数据库的两级(三级同理绑定)省市选择器——wheel选择器的学习使用

最近离职,准备把精力全放在毕设的项目上,做到城市选择这一块,也见识了wheel组件的强大~

 

先上效果:

模拟器效果有点渣哎~

上主代码:

 

/**
 *  基于数据库的两级wheel,三级wheel同理,用相应Id衔接起来即可~
 *  
 * @author sen  
 * 一直以为需要三级wheel,做到取数据那一块的时候发现city没数据啊戳~是的,数据库是自己从网站抓取生成的,不保证完整性,
 * 完整的省市区三层数据库同分享在assets文件夹了,有需要的哥们可以写写,逻辑简单~
 */
public class MainActivity extends Activity implements OnWheelChangedListener {

	private final String DB_NAME = "sen.db";
	/**
	 * 模拟器下测试路径,真机或者genymotion的话记得修改路径~
	 */
	private final String DB_PATH = "/data/data/com.ob.main/databases/";

	private WheelView wheel_province;
	private WheelView wheel_district;
	/**
	 * 所有省
	 */
	private String[] mProvinceDatas;

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

		initData();
	}
	/**
	 * 拷贝assets数据库到本地文件夹下
	 */
	private void initData() {
		try {
			copyDataBase();
		} catch (IOException e) {
			e.printStackTrace();
			Log.e("写入数据库失败", "~~~~~~~~~");
		}
		//从数据库获取省一级的数据
		mProvinceDatas = new SqlHelper(this).getProvinceData();
		initAreaSelect();
	}
	/**
	 * 初始化城市选择器
	 */
	private void initAreaSelect() {
		wheel_province = (WheelView) findViewById(R.id.wheel_province);
		wheel_district = (WheelView) findViewById(R.id.wheel_district);
		wheel_province.addChangingListener(this);
		wheel_district.addChangingListener(this);
		//设置适配器,数组类型的数据即可~
		wheel_province.setViewAdapter(new ArrayWheelAdapter<String>(
				MainActivity.this, mProvinceDatas));
		// 设置滑动监听和显示的最大条数
		wheel_province.setVisibleItems(7);
		wheel_district.setVisibleItems(7);
		updateDistricts();
	}

	@Override
	public void onChanged(WheelView wheel, int oldValue, int newValue) {
		if (wheel == wheel_province) {
			// 根据省数据改变市数据
			updateDistricts();
		} 
	}	
	/**
	 * 根据当前省更新市一级数据
	 */
	private void updateDistricts() {
//		得到正在展示市级数据的省级Id
		int provinceId = wheel_province.getCurrentItem();
		String[] districtData = new SqlHelper(this).getDistrictData(String.valueOf(provinceId));
//		设置适配器,与province数组数据相对应的数据即可~
		wheel_district.setViewAdapter(new ArrayWheelAdapter<String>(this, districtData));
		wheel_district.setCurrentItem(0);
	}

	
	/**
	 * 拷贝assets数据库到本地文件夹下
	 * 
	 * @throws IOException
	 */
	private void copyDataBase() throws IOException {
		boolean checkDataBase = checkDataBase();
		if (checkDataBase) {
			Log.e("数据库已存在", "~~~");
		} else {
			Log.e("开始写入数据库", "~~~");
			//创建文件
//			File file = new File(DB_PATH);
//			if(!file.exists()){
//				file.mkdirs();
//			}
			InputStream myInput = this.getAssets().open(DB_NAME);
			String outFileName = DB_PATH + DB_NAME;
			OutputStream myOutput = new FileOutputStream(outFileName);
			byte[] buffer = new byte[1024];
			int length;
			while ((length = myInput.read(buffer)) > 0) {
				myOutput.write(buffer, 0, length);
			}
			myOutput.flush();
			myOutput.close();
			myInput.close();
		}
	}
	/**
	 * 检查数据库是否存在
	 * @return boolean
	 */
	private boolean checkDataBase() {
		SQLiteDatabase checkDB = null;
		String myPath = DB_PATH + DB_NAME;
		try {
			checkDB = SQLiteDatabase.openDatabase(myPath, null,
					SQLiteDatabase.OPEN_READONLY);
		} catch (SQLiteException e) {
			// database does't exist yet.
		}
		if (checkDB != null) {
			checkDB.close();
		}
		return checkDB != null ? true : false;
	}

}

嗯..逻辑挺简单,把assets下文件夹的数据库写入APP,然后用相应ID读出相应数据,分别和wheel控件绑定,注释很详细~

这里要注意下写入的路径,我用的ADT,genymotion和真机的话需要修改相应的APP下路径.

读出数据的Java类:

 

public class SqlHelper {
	
	private DBOpenHelper helper;
	public SqlHelper(Context context){
		//获取数据库连接
		helper=new DBOpenHelper(context);
	}
	/**
	 * 省级数据
	 * @return 省级String数组
	 */
	public String[] getProvinceData(){
		SQLiteDatabase db = helper.getReadableDatabase();
		Cursor c = db.rawQuery("Select name From province", null);
		int count = c.getCount();
		String[] proStr = new String[count];
		int i = 0;
		//-1开始的下标
		while(c.moveToNext()){
			proStr[i] = c.getString(c.getColumnIndex("name"));
			i++;
		}
		c.close();
		db.close();
		return proStr;
	}
	/**
	 * 得到省级相应的市级数据
	 * @param provinceId 省级Id
	 * @return 市级String数组
	 */
	public String[] getDistrictData(String provinceId){
		SQLiteDatabase db = helper.getReadableDatabase();
		Cursor c = db.rawQuery("Select name From district where provinceId = ?", new String[]{provinceId});
		int count = c.getCount();
		String[] disStr = new String [count];
		int i =0;
		while(c.moveToNext()){
			disStr[i] = c.getString(c.getColumnIndex("name"));
			i++;
		}
		c.close();
		db.close();
		return disStr;
	}	
}

数据库打开帮助类:

 

public class DBOpenHelper extends SQLiteOpenHelper {
	
	public DBOpenHelper(Context context) {
		super(context, "sen.db", null, 1);
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		// 版本未更新执行的方法
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// 版本更新执行的方法,可以用来达到修改数据库的效果
		// db.execSQL("Alter Table persen Add ? Integer");
	}

//	/**
//	 * 删除数据库
//	 * 
//	 * @param context
//	 * @return
//	 */
//
//	public boolean deleteDatabase(Context context) {
//		return context.deleteDatabase("sen.db");
//	}

}


xml:

<LinearLayout 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:orientation="horizontal">

    <kankan.wheel.widget.WheelView
        android:id="@+id/wheel_province"
        android:layout_width="0dip"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <kankan.wheel.widget.WheelView
        android:id="@+id/wheel_district"
        android:layout_width="0dip"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

</LinearLayout>


...嗯~~~~~demo~基于数据库的两级省市选择器——wheel选择器的学习使用 

 

用在项目上的一些改变,代码补充在这里,demo就偷个懒了~^_^

wheel组件改变样式有点黑,文字背景什么的还set不出来...

当时有点懵,这么强大的开源组件,不应该啊~

还好组件的包很明显,拓展性本来打算看自己了~

 

没想到柳暗花明一村美女都藏在里面哎~

AbstractWheelTextAdapter.java  下面找到了set样式,跟踪发现可以改变...难道是我set的方式不对.. = =!

修改为自己需要的,嗯...样式就这样~~~
 

 之后就是双击选中了,这个在网上源码很多,我就放上来做参考~

class onDoubleClickListener implements OnTouchListener {
		int count = 0;
		int firClick = 0;
		int secClick = 0;
		@Override
		public boolean onTouch(View v, MotionEvent event) {
			if (MotionEvent.ACTION_DOWN == event.getAction()) {
				count++;
				if (count == 1) {
					firClick = (int) System.currentTimeMillis();
				} else if (count == 2) {
					secClick = (int) System.currentTimeMillis();
					if (secClick - firClick < 1000) {// 第二次点击的间隔小于1s
					//逻辑处理
					}
					count = 0;
					firClick = 0;
					secClick = 0;
				}
			}
			//返回true则消耗掉其他触摸之类的点击事件  详见郭神or洋神的事件分发机制
			return false;
		}

	}

嗯~最后设置一下监听

wheel_district.setOnTouchListener(new onDoubleClickListener());

 

ok~有遇到更多的细节再更新..



 

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值