Android:Moring-早安鬧鐘開發(fā)過程記錄(四)

FragmentMenu側(cè)滑菜單界面實現(xiàn)

1.界面實現(xiàn)

側(cè)滑菜單.jpg
  • 界面顯示比較簡單,因為用的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ù)庫拷貝到本地
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" />
寫到這兒,這個項目基本上比較重要的地方都總結(jié)完了纤子,另外為了防止應(yīng)用被無情的殺死菊匿,我翻看了很多大神的博客付呕,目前比較有效的應(yīng)該是開啟一個獨立進(jìn)程相互監(jiān)視,互相扶持~跌捆,后面有空的話再補一篇吧徽职!

完結(jié)!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末佩厚,一起剝皮案震驚了整個濱河市姆钉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌抄瓦,老刑警劉巖潮瓶,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異钙姊,居然都是意外死亡毯辅,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進(jìn)店門煞额,熙熙樓的掌柜王于貴愁眉苦臉地迎上來思恐,“玉大人,你說我怎么就攤上這事膊毁≌陀ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵婚温,是天一觀的道長描焰。 經(jīng)常有香客問我,道長栅螟,這世上最難降的妖魔是什么荆秦? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮力图,結(jié)果婚禮上步绸,老公的妹妹穿的比我還像新娘。我一直安慰自己搪哪,他們只是感情好靡努,可當(dāng)我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著晓折,像睡著了一般惑朦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上漓概,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天漾月,我揣著相機(jī)與錄音,去河邊找鬼胃珍。 笑死梁肿,一個胖子當(dāng)著我的面吹牛蜓陌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吩蔑,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼钮热,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了烛芬?” 一聲冷哼從身側(cè)響起隧期,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎赘娄,沒想到半個月后仆潮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡遣臼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年性置,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片揍堰。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡鹏浅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出个榕,到底是詐尸還是另有隱情篡石,我是刑警寧澤芥喇,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布西采,位于F島的核電站,受9級特大地震影響继控,放射性物質(zhì)發(fā)生泄漏械馆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一武通、第九天 我趴在偏房一處隱蔽的房頂上張望霹崎。 院中可真熱鬧,春花似錦冶忱、人聲如沸尾菇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽派诬。三九已至,卻和暖如春链沼,著一層夾襖步出監(jiān)牢的瞬間默赂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工括勺, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留缆八,地道東北人曲掰。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像奈辰,于是被迫代替她去往敵國和親栏妖。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,851評論 2 361

推薦閱讀更多精彩內(nèi)容