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

FragmentMenu側滑菜單界面實現

1.界面實現

側滑菜單.jpg
  • 界面顯示比較簡單,因為用的SlidingMenu的第三方庫所以實現起來比較簡單
    github地址:https://github.com/jfeinstein10/SlidingMenu
    -在新建一個側滑菜單的布局文件,布局寫成什么樣菜單就長什么樣
    顯示菜單的Activity需要繼承SlidingFragmentActivity
setBehindContentView(R.layout.menu_home);
//獲取到slidingMenu對象SlidingMenu slidingMenu = getSlidingMenu();
slidingMenu.setMode(SlidingMenu.RIGHT);//設置菜單在哪一邊
slidingMenu.setShadowWidthRes(R.dimen.shadow_width);
//設置陰影圖片
slidingMenu.setShadowDrawable(R.drawable.shadow);
//設置為全屏拉出菜單
slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
//設置菜單寬度
slidingMenu.setBehindOffset(200);

側滑菜單就可以愉快的開始工作了

2.功能實現

天氣和震動比較簡單,用SP記錄一下用戶的選擇就OK了
比較復雜的是更換城市和音量改變

  • 更換城市


    changecity.jpg
    • 在用戶輸入的時候給用戶動態提示
      • 配置數據庫
        首先配置好數據庫,在第一次啟動應用的時候將數據庫拷貝到本地
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);
}
  定義一個工具類進行查找數據庫,這里需要進行模糊查找
  `"select 字段名 from 表名 where 字段名like '%" + 用戶輸入的字符+ "%'"`
  將包含該字符的數據全部找出,返回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;
}
- 界面實現
  Android自己有一個控件叫AutoCompleteTextView-自動補全文本編輯框,用這個控件可以實現這個效果,與數據庫建立連接就可以了。
  我沒有用AutoCompleteTextView,而是自己實現這個效果。分析一下這個控件的效果不難得出就是一個EditText和一個ListView就可以實現
  - 布局文件:
<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的寬高,所以在初始化的時候將ListView的狀態設置為gone,不設置也沒有關系,因為代碼中會設置輸入一個字符后才開啟提示
- 代碼實現
首先將布局塞給對話框

dao = new CityDao();//數據庫讀取工具
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設置一個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;
      }

適配器設置好了以后,就需要監聽文本框的輸入情況來動態改變ListView
EditText有一個方法addTextChangedListener(TextWather tw);用于監聽文本框的文字改變,在onTextChanged中實現顯示提示

@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);
          }
}

每當文字發生改變時獲取到用戶輸入的字符,查找數據庫更新cityList并刷新UI。
還有一個問題,由于每次查詢返回的數據條數不一致,導致有時候數據條數太多ListView太長被鍵盤蓋住了。這里還需要限制一下ListView的高度
int itemCount=adapter.getCount()
獲取到當前的數據條數,如果條數大于四條就將ListView限制死,如果小于四條就以ListView本身的高度為準,在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);

最后一步,監聽ListView的Item點擊事件,實現用戶點擊提示補全編輯框
點擊后提示消失

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的時候要播放鈴聲(不然調屁的音量啊!)
    設置SeekBar的監聽,在onProgressChanged()中去實現邏輯
    setOnSeekBarChangeListener(OnSeekBarChangeListener listener);
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
          playAlarmMusic();//播放音樂
          setSystemVolume(progress);//調節音量
          PrefUtils.putInt(mActivity, ConsUtils.ALARM_VOLUME, progress);//記錄音量
}

現在依次來寫出這兩個方法吧,首先是播放音樂

//播放音樂
      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設置為某一個類型,否則是沒有什么卵用的,因為是鬧鐘所以就設置為STREAM_ALARM就好
另外因為每次滑動都會調用該方法,所以先判斷一下當前是否已經在播放了,在播放了就不有再播放了。
isMusicOn是做一個標記為后面關掉音樂用

- AudioManager來設置音量

AudioManager是系統服務通過getSystem(AUDIO_SERVICE)得到實例

private void setSystemVolume(int progress) {
          //獲取到音量調節管理器
          int maxVolume= mAudioManager.getStreamMaxVolume(AudioManager.STREAM_ALARM);
          int setVolume=(maxVolume*progress)/100;
          mAudioManager.setStreamVolume(AudioManager.STREAM_ALARM, setVolume, 0);
}

setStreamVolume()中的第二個參數的解釋是傳入音量的絕對值,我的理解是音量絕對值可能不一定是百分數,所以先獲取到手機的最大音量值,然后通過百分比計算應該傳入的絕對值(一定要先乘再除啊,否則int類型你懂得,誤差會比較大),具體絕對值是什么我也沒去研究,不過這樣做應該沒有太大的問題。
獲取和修改系統音量需要用到的權限

<uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
寫到這兒,這個項目基本上比較重要的地方都總結完了,另外為了防止應用被無情的殺死,我翻看了很多大神的博客,目前比較有效的應該是開啟一個獨立進程相互監視,互相扶持~,后面有空的話再補一篇吧!

完結!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,698評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,202評論 3 426
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,742評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,580評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,297評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,688評論 1 327
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,693評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,875評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,438評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,183評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,384評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,931評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,612評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,022評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,297評論 1 292
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,093評論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,330評論 2 377

推薦閱讀更多精彩內容