FragmentMenu側(cè)滑菜單界面實現(xiàn)
1.界面實現(xiàn)
- 界面顯示比較簡單,因為用的SlidingMenu的第三方庫所以實現(xiàn)起來比較簡單
github地址:https://github.com/jfeinstein10/SlidingMenu
-在新建一個側(cè)滑菜單的布局文件脚猾,布局寫成什么樣菜單就長什么樣
顯示菜單的Activity需要繼承SlidingFragmentActivity
setBehindContentView(R.layout.menu_home);
//獲取到slidingMenu對象SlidingMenu slidingMenu = getSlidingMenu();
slidingMenu.setMode(SlidingMenu.RIGHT);//設(shè)置菜單在哪一邊
slidingMenu.setShadowWidthRes(R.dimen.shadow_width);
//設(shè)置陰影圖片
slidingMenu.setShadowDrawable(R.drawable.shadow);
//設(shè)置為全屏拉出菜單
slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
//設(shè)置菜單寬度
slidingMenu.setBehindOffset(200);
側(cè)滑菜單就可以愉快的開始工作了
2.功能實現(xiàn)
天氣和震動比較簡單炭臭,用SP記錄一下用戶的選擇就OK了
比較復(fù)雜的是更換城市和音量改變
-
更換城市
changecity.jpg- 在用戶輸入的時候給用戶動態(tài)提示
- 配置數(shù)據(jù)庫
首先配置好數(shù)據(jù)庫锯厢,在第一次啟動應(yīng)用的時候?qū)?shù)據(jù)庫拷貝到本地
- 配置數(shù)據(jù)庫
- 在用戶輸入的時候給用戶動態(tài)提示
in=getResources().getAssets().open(dbName);
out=new FileOutputStream(file);
byte[] buffer=new byte[1024];
int len=0;
while((len=in.read(buffer))!=-1){
out.write(buffer, 0, len);
}
定義一個工具類進(jìn)行查找數(shù)據(jù)庫枯冈,這里需要進(jìn)行模糊查找
`"select 字段名 from 表名 where 字段名like '%" + 用戶輸入的字符+ "%'"`
將包含該字符的數(shù)據(jù)全部找出茵瀑,返回String列表
public ArrayList<String> find(String input){
String path="data/data/com.joe.lazyalarm/files/china_Province_city_zone.db";
SQLiteDatabase sql=SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
//模糊查詢
ArrayList<String> cityList=new ArrayList<String>();
Cursor cursor=sql.rawQuery("select CityName from T_City where CityName like '%" + input + "%'", null);
while (cursor.moveToNext()){
String cityName=cursor.getString(cursor.getColumnIndex("CityName"));
cityList.add(cityName);
}
sql.close();
cursor.close();
return cityList;
}
- 界面實現(xiàn)
Android自己有一個控件叫AutoCompleteTextView-自動補全文本編輯框腕铸,用這個控件可以實現(xiàn)這個效果惜犀,與數(shù)據(jù)庫建立連接就可以了。
我沒有用AutoCompleteTextView狠裹,而是自己實現(xiàn)這個效果虽界。分析一下這個控件的效果不難得出就是一個EditText和一個ListView就可以實現(xiàn)
- 布局文件:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<EditText
android:id="@id/et_change_city"
android:hint="例如:重慶"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ListView
android:visibility="gone"
android:layout_below="@id/et_change_city"
android:id="@id/lv_change_city"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
說明:我是通過setView()將布局添加到對話框中,為了省事并沒有讓ListView懸浮在對話框上面涛菠,如果需要懸浮的話改一下布局文件就可以了
因為ListView沒有懸浮莉御,必然會占用dialog的寬高撇吞,所以在初始化的時候?qū)istView的狀態(tài)設(shè)置為gone,不設(shè)置也沒有關(guān)系礁叔,因為代碼中會設(shè)置輸入一個字符后才開啟提示
- 代碼實現(xiàn)
首先將布局塞給對話框
dao = new CityDao();//數(shù)據(jù)庫讀取工具
cityList = new ArrayList<String>();//查找到的城市列表
final View autoLayout = View.inflate(mActivity, R.layout.auto_edit_view, null);
final EditText autoText = (EditText) autoLayout.findViewById(R.id.et_change_city);
ListView listHint = (ListView) autoLayout.findViewById(R.id.lv_change_city);
builder.setView(autoLayout);
然后為ListView設(shè)置一個Adapter
Adapter的getView()方法
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView==null){
convertView=View.inflate(mActivity,R.layout.item_change_city,null);
holder=new ViewHolder();
holder.hint= (TextView) convertView.findViewById(R.id.tv_hint_city);
convertView.setTag(holder);
}else{
holder= (ViewHolder) convertView.getTag();
}
holder.hint.setText(cityList.get(position));
return convertView;
}
適配器設(shè)置好了以后牍颈,就需要監(jiān)聽文本框的輸入情況來動態(tài)改變ListView
EditText有一個方法addTextChangedListener(TextWather tw);用于監(jiān)聽文本框的文字改變,在onTextChanged中實現(xiàn)顯示提示
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.length() > 0) {
Log.d("changecity", "顯示listview");
//如果字符大于0琅关,顯示listview
listHint.setVisibility(View.VISIBLE);
cityList = dao.find(s.toString());
adapter.notifyDataSetChanged();
} else {
listHint.setVisibility(View.GONE);
}
}
每當(dāng)文字發(fā)生改變時獲取到用戶輸入的字符煮岁,查找數(shù)據(jù)庫更新cityList并刷新UI。
還有一個問題涣易,由于每次查詢返回的數(shù)據(jù)條數(shù)不一致画机,導(dǎo)致有時候數(shù)據(jù)條數(shù)太多ListView太長被鍵盤蓋住了。這里還需要限制一下ListView的高度
int itemCount=adapter.getCount()
獲取到當(dāng)前的數(shù)據(jù)條數(shù)都毒,如果條數(shù)大于四條就將ListView限制死色罚,如果小于四條就以ListView本身的高度為準(zhǔn)碰缔,在onTextChanged中添加
int itemCount = adapter.getCount();
Log.d("changecity", "count" + itemCount);
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) listHint.getLayoutParams();
if (itemCount > 4) {
params.height = 500;
} else {
params.height = RelativeLayout.LayoutParams.WRAP_CONTENT;
}
listHint.setLayoutParams(params);
最后一步账劲,監(jiān)聽ListView的Item點擊事件,實現(xiàn)用戶點擊提示補全編輯框
點擊后提示消失
listHint.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView cityName= (TextView) view.findViewById(R.id.tv_hint_city);
autoText.setText(cityName.getText());
listHint.setVisibility(View.GONE);
}
});
大功告成金抡!
- 音量控制
利用SeekBar來改變音量瀑焦,首先在用戶滑動了SeekBar的時候要播放鈴聲(不然調(diào)屁的音量啊98巍)
設(shè)置SeekBar的監(jiān)聽榛瓮,在onProgressChanged()中去實現(xiàn)邏輯
setOnSeekBarChangeListener(OnSeekBarChangeListener listener);
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
playAlarmMusic();//播放音樂
setSystemVolume(progress);//調(diào)節(jié)音量
PrefUtils.putInt(mActivity, ConsUtils.ALARM_VOLUME, progress);//記錄音量
}
現(xiàn)在依次來寫出這兩個方法吧巫击,首先是播放音樂
//播放音樂
private void playAlarmMusic() {
if(mPlayer==null){
try {
mPlayer=new MediaPlayer();
AssetFileDescriptor assetFileDescriptor=mActivity.getAssets().openFd("everybody.mp3");
mPlayer.reset();
mPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
mPlayer.setDataSource(assetFileDescriptor.getFileDescriptor(), assetFileDescriptor.getStartOffset(), assetFileDescriptor.getLength());
mPlayer.setVolume(1f, 1f);
mPlayer.prepare();
mPlayer.start();
isMusicOn=true;
} catch (IOException e) {
e.printStackTrace();
}
}
}
必須將mPlayer的AudioStreamType設(shè)置為某一個類型禀晓,否則是沒有什么卵用的,因為是鬧鐘所以就設(shè)置為STREAM_ALARM就好
另外因為每次滑動都會調(diào)用該方法坝锰,所以先判斷一下當(dāng)前是否已經(jīng)在播放了粹懒,在播放了就不有再播放了。
isMusicOn是做一個標(biāo)記為后面關(guān)掉音樂用
- AudioManager來設(shè)置音量
AudioManager是系統(tǒng)服務(wù)通過getSystem(AUDIO_SERVICE)得到實例
private void setSystemVolume(int progress) {
//獲取到音量調(diào)節(jié)管理器
int maxVolume= mAudioManager.getStreamMaxVolume(AudioManager.STREAM_ALARM);
int setVolume=(maxVolume*progress)/100;
mAudioManager.setStreamVolume(AudioManager.STREAM_ALARM, setVolume, 0);
}
setStreamVolume()中的第二個參數(shù)的解釋是傳入音量的絕對值顷级,我的理解是音量絕對值可能不一定是百分?jǐn)?shù)凫乖,所以先獲取到手機(jī)的最大音量值,然后通過百分比計算應(yīng)該傳入的絕對值(一定要先乘再除啊弓颈,否則int類型你懂得帽芽,誤差會比較大),具體絕對值是什么我也沒去研究翔冀,不過這樣做應(yīng)該沒有太大的問題导街。
獲取和修改系統(tǒng)音量需要用到的權(quán)限
<uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />