Android学习之——APP番茄工作法——小结(2)

来源:互联网 发布:apt模型与capm模型知乎 编辑:程序博客网 时间:2024/05/01 13:46
[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1.   
今天,我的第一个APP:番茄工作法 1.0版本终于终于终于完成了,虽然还有很多很多的不足之处,但是,终归算是告一个段落了。
第一款小应用,其中的艰辛冷暖自知,各种摸爬滚打,各种度娘谷歌。
简单讲解下其中碰到的问题:
问题一:android.support.v4.app.Fragment 包下没有PreferenceFragment的问题。
起初做的设置界面太过难看,所以打算使用谷歌力推的碎片机制,但是发现v4包下面居然没有PreferenceFragment类。然后各种搞不定。
最后在谷歌的帮助下顺利找到实现方法(花了我将近一个礼拜的时间,泪奔,新手不解释...)
https://github.com/kolavar/android-support-v4-preferencefragment
进入上面的链接下载这个library。
实现方式和android.preference.PreferenceFragment 下的方式一样,具体代码如下:
[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. public class fragment3 extends PreferenceFragment{  
  2.     public static fragment3 newInstance(Bundle bundle) {  
  3.         fragment3 frag = new fragment3();  
  4.         frag.setArguments(bundle);  
  5.         return frag;  
  6.     }  
  7.     @Override  
  8.     public void onCreate(Bundle savedInstanceState) {  
  9.         super.onCreate(savedInstanceState);  
  10.         addPreferencesFromResource(R.xml.preferences);    
  11.         Log.v("huahua""fragment3-->onCreate()");  
  12.     }  
  13. }  
具体代码我会在下面全部放出来
其中有一点不足,相当遗憾:preferences.xml中的RingtonePreference设置铃声的数据一直无法保存到SharedPreferences中去,导致无法设定铃声。如果有大神能够解决  感激不敬。
 

注意在preferences.xml中最好不要设定自定义的View,因为这个问题困扰了我很久。
关于PreferenceFragment的其他用法:http://www.oschina.net/question/565065_107985
由于PreferenceFragment中没有SeekBar 重写SeekBar的方式介绍:http://www.eoeandroid.com/thread-115052-1-1.html

问题二:保存简单数据的问题
在应用中可能需要保存一些很简单的数据,如界面上显示一个执行任务的次数等,这些简单数据可以放到SharedPreferences,它会将数据保存到一个xml中去,具体的使用代码如下:
[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. SharedPreferences mySharedPreferences = getActivity().getSharedPreferences("TomatoCount",  
  2.         Activity.MODE_PRIVATE);//获取SharedPreferences 中的值,TomatoCount表示保存的文件名称  
  3. String dateStr = mySharedPreferences.getString("date""2001-01-01");//获取字符串  
  4. todayTomatoCount = mySharedPreferences.getInt("todayTomatoCount"0);//获取存储的今日番茄时间,获取int型数据,如果不存在默认设置为0  
  5. allTomatoCount = mySharedPreferences.getInt("allTomatoCount"0);//获取存储的合计番茄时间  
  6. String dateNowString = (new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())).format(new java.util.Date());  
  7. if (!dateStr.equals(dateNowString)) {//判断存储时间是否和当前时间在同一天  
  8.     todayTomatoCount=0;  
  9.     SharedPreferences.Editor editor = mySharedPreferences.edit();  
  10.     editor.putInt("todayTomatoCount", todayTomatoCount);//写入数据到Editor 其中第一个参数是字段的名称,第二个参数是字段的值,该写入的是int类型  
  11.     editor.commit();//提交,写入到xml文件中  
  12. }  

问题三:修改字体
在assets文件夹下新建fonts文件夹,将需要的字体(*.ttf)放入到该文件夹下,代码中使用该字体的方法如下:
[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. //修改字体  
  2. Typeface fontFace = Typeface.createFromAsset(getActivity().getAssets(), "fonts/Roboto-Thin.ttf");  
  3. tomatoTxtView.setTypeface(fontFace);  

问题四:如何在PreferenceFragment实现类中如果要实时的获取修改的值等
如果当ListPreference中的值改变以后,我要在ListPreference的副标题中显示改变的值该如何操作呢:重写onSharedPreferenceChanged方法
如果当我们需要点击preference进入到另外一个页面时,或者我们需要跳转到网页时,该如何操作呢:重写onPreferenceTreeClick方法
[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. public class SettingPreferenceFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener {  
  2.     ListPreference lstPre_TomatoTime_value, lstPre_BreakTime_value;  
  3.     public SettingPreferenceFragment() {  
  4.         // TODO 自动生成的构造函数存根  
  5.     }  
  6.     @Override  
  7.     public void onCreate(Bundle paramBundle) {  
  8.         // TODO 自动生成的方法存根  
  9.         super.onCreate(paramBundle);  
  10.         addPreferencesFromResource(R.xml.preferences);  
  11.         SharedPreferences prefs=PreferenceManager.getDefaultSharedPreferences(getActivity());  
  12.         prefs.registerOnSharedPreferenceChangeListener(this);  
  13.         lstPre_TomatoTime_value=(ListPreference)findPreference("TomatoTime_value");  
  14.         lstPre_BreakTime_value=(ListPreference)findPreference("BreakTime_value");  
  15.         lstPre_TomatoTime_value.setSummary(lstPre_TomatoTime_value.getEntry());  
  16.         lstPre_BreakTime_value.setSummary(lstPre_BreakTime_value.getEntry());  
  17.     }  
  18.     @Override  
  19.     public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,  
  20.             String key) {  
  21.         // TODO 自动生成的方法存根  
  22.         if (key.equals("TomatoTime_value")) {  
  23.             lstPre_TomatoTime_value.setSummary(lstPre_TomatoTime_value.getEntry());  
  24.         }  
  25.         if (key.equals("BreakTime_value")) {  
  26.             lstPre_BreakTime_value.setSummary(lstPre_BreakTime_value.getEntry());  
  27.         }  
  28.     }  
  29.        
  30.     @Override  
  31.     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,  
  32.             Preference preference) {  
  33.         // TODO 自动生成的方法存根  
  34.         if (preference.getKey().equals("clearCount")) {  
  35.             alertDialogShow();  
  36.         }  
  37.         if (preference.getKey().equals("aboutTomatoTask")) {  
  38.             Uri uri = Uri.parse("http://baike.baidu.com/link?url=b7rlhS6YssFup2xqAjnw9__6VsQnyhtVT8Gx_-qwckUE4IZ-ns6i_jw9w_aKH-C_sjWheb9NFR_GZcfUII0bV_");  
  39.             startActivity(new Intent(Intent.ACTION_VIEW,uri));  
  40.         }  
  41.         return false;  
  42.     }  
  43.        
  44.     /** 
  45.      * 显示AlertDialog 
  46.      */  
  47.     private void alertDialogShow() {  
  48.         new AlertDialog.Builder(getActivity()).setTitle("清除?").setMessage("是否清除计数?\n注:该操作不可逆!").setPositiveButton("清除"new DialogInterface.OnClickListener() {  
  49.                
  50.             @Override  
  51.             public void onClick(DialogInterface dialog, int which) {  
  52.                 // TODO 自动生成的方法存根  
  53.                 SharedPreferences mySharedPreferences = getActivity().getSharedPreferences("TomatoCount",  
  54.                         Activity.MODE_PRIVATE);  
  55.                 SharedPreferences.Editor editor = mySharedPreferences.edit();  
  56.                 editor.putInt("todayTomatoCount"0);  
  57.                 editor.putInt("allTomatoCount"0);  
  58.                 editor.commit();  
  59.                 Toast.makeText(getActivity(), "清除成功!", Toast.LENGTH_SHORT).show();  
  60.             }  
  61.         }).setNegativeButton("取消"new DialogInterface.OnClickListener() {  
  62.             @Override  
  63.             public void onClick(DialogInterface dialog, int which) {  
  64.                 // TODO 自动生成的方法存根  
  65.             }  
  66.         }).create().show();  
  67.     }  
  68. }  

问题五:如何实现倒计时

在android 已经给我们封装好了一个倒计时的类,我们直接拿来实现就可以啦,具体过程如下:
[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. private TimeCount time;  
2. new 一个TimeCount, timeSpan是需要倒计时的时间(毫秒),1000是倒计时间隔,这里是一秒
[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. time = new TimeCount(timeSpan, 1000);// 构造CountDownTimer对象  
  2. time.start();  
3. 写内部类TimeCount 继承自CountDownTimer 其中onTick表示,在上述设定的倒计时间隔期间做什么,onFinish表示计时完毕时做什么
[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. class TimeCount extends CountDownTimer {  
  2.     public TimeCount(long millisInFuture, long countDownInterval) {  
  3.         super(millisInFuture, countDownInterval);// 参数依次为总时长,和计时的时间间隔  
  4.     }  
  5.     /** 
  6.      * 计时过程显示 
  7.      */  
  8.     @Override  
  9.     public void onTick(long millisUntilFinished) {  
  10.         // TODO 自动生成的方法存根  
  11.     }  
  12.     /** 
  13.      * 计时完毕时触发 
  14.      */  
  15.     @Override  
  16.     public void onFinish() {  
  17.         // TODO 自动生成的方法存根  
  18.     }  
  19. }  

问题六:触发点击事件:当我们点击返回按键时,是否弹出AlertDialog提示框,或者是提示“再按一次退出”的实现:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. @Override  
  2. public boolean onKeyDown(int keyCode, KeyEvent event) {  
  3.     if (flag == 2) {  
  4.         if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {  
  5.             AlertDialog.Builder alertBuilder = new AlertDialog.Builder(  
  6.                     MainActivity.this);  
  7.             alertBuilder  
  8.                     .setTitle("放弃?")  
  9.                     .setMessage("是否放弃这个番茄并退出吗?")  
  10.                     .setPositiveButton("确定",  
  11.                             new DialogInterface.OnClickListener() {  
  12.    
  13.                                 @Override  
  14.                                 public void onClick(DialogInterface dialog,  
  15.                                         int which) {  
  16.                                     // TODO 自动生成的方法存根  
  17.                                     time.cancel();  
  18.                                     MainActivity.this.finish();  
  19.                                 }  
  20.                             })  
  21.                     .setNegativeButton("取消",  
  22.                             new DialogInterface.OnClickListener() {  
  23.    
  24.                                 @Override  
  25.                                 public void onClick(DialogInterface dialog,  
  26.                                         int which) {  
  27.                                     // TODO 自动生成的方法存根  
  28.                                     dialog.cancel();  
  29.                                 }  
  30.                             }).create();  
  31.             alertBuilder.show();  
  32.         }  
  33.     } else {  
  34.         if (keyCode == KeyEvent.KEYCODE_BACK  
  35.                 && event.getAction() == KeyEvent.ACTION_DOWN) {  
  36.             if ((System.currentTimeMillis() - exitTime) > 2000) {  
  37.                 Toast.makeText(getApplicationContext(), "再按一次退到主界面",  
  38.                         Toast.LENGTH_SHORT).show();  
  39.                 exitTime = System.currentTimeMillis();  
  40.             } else {  
  41.                 time.cancel();  
  42.                 finish();  
  43.                 System.exit(0);  
  44.             }  
  45.             return true;  
  46.         }  
  47.         return super.onKeyDown(keyCode, event);  
  48.     }  
  49.     return true;  
  50. }  

问题七:震动的实现

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. private Vibrator vibrator;  
[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. //开启震动  
  2. vibrator =(Vibrator)getSystemService(Context.VIBRATOR_SERVICE);  
  3. long [] pattern = {200,500,200,500,1200,500,200,500};   // 停止 开启 停止 开启    
  4. vibrator.vibrate(pattern,-1);           //重复两次上面的pattern 如果只想震动一次,index设为-1   

问题八:重写ProgressBar,设置为圆形进度条:

来源:http://www.pocketdigi.com/20130712/1136.html

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.android.tomatotask;  
  2. import android.content.Context;  
  3. import android.graphics.Canvas;  
  4. import android.graphics.Color;  
  5. import android.graphics.Paint;  
  6. import android.graphics.RectF;  
  7. import android.util.AttributeSet;  
  8. import android.view.View;  
  9. public class CircleProgressBar extends View {  
  10.     private int maxProgress = 10;//最大进度  
  11.     private int progress = 0;//当前进度  
  12.     private int progressStrokeWidth = 6;//线宽  
  13.     // 画圆所在的矩形区域  
  14.     RectF oval;  
  15.     Paint paint;  
  16.     public CircleProgressBar(Context context) {  
  17.         super(context);  
  18.         // TODO 自动生成的构造函数存根  
  19.     }  
  20.     public CircleProgressBar(Context context, AttributeSet attrs) {  
  21.         super(context, attrs);  
  22.         // TODO 自动生成的构造函数存根  
  23.         oval = new RectF();  
  24.         paint = new Paint();  
  25.     }  
  26.     public CircleProgressBar(Context context, AttributeSet attrs, int defStyle) {  
  27.         super(context, attrs, defStyle);  
  28.         // TODO 自动生成的构造函数存根  
  29.     }  
  30.     @Override  
  31.     protected void onDraw(Canvas canvas) {  
  32.         super.onDraw(canvas);     
  33.         /** 
  34.          * 画最外层的大圆环 
  35.          */  
  36.         int centre = getWidth()/2//获取圆心的x坐标  
  37.         int radius = (int) (centre - progressStrokeWidth/2); //圆环的半径  
  38.         paint.setColor(Color.WHITE);//(roundColor); //设置圆环的颜色  
  39.         paint.setStyle(Paint.Style.STROKE); //设置空心  
  40.         paint.setStrokeWidth(progressStrokeWidth); //设置圆环的宽度  
  41.         paint.setAntiAlias(true);  //消除锯齿   
  42.         canvas.drawCircle(centre, centre, radius, paint); //画出圆环          
  43.         /** 
  44.          * 画圆弧 ,画圆环的进度 
  45.          */         
  46.         //设置进度是实心还是空心  
  47.         paint.setStrokeWidth(progressStrokeWidth); //设置圆环的宽度  
  48.         paint.setColor(Color.rgb(0x570x870xb6));  //设置进度的颜色   
  49.         RectF oval = new RectF(centre - radius, centre - radius, centre  
  50.                 + radius, centre + radius);  //用于定义的圆弧的形状和大小的界限  
  51.             paint.setStyle(Paint.Style.STROKE);  
  52.             canvas.drawArc(oval, -90360 * progress / maxProgress, false, paint);  //根据进度画圆弧  绘制白色圆圈,即进度条背景  
  53.     }     
  54.     public int getMaxProgress(){  
  55.         return maxProgress;  
  56.     }     
  57.     public void setMaxProgress(int maxProgress){  
  58.         this.maxProgress = maxProgress;  
  59.     }     
  60.     public void setProgress(int progress){  
  61.         this.progress = progress;  
  62.         this.invalidate();  
  63.     }     
  64.     public void setProgressNotInUiThread(int progress){  
  65.         this.progress = progress;  
  66.         this.postInvalidate();  
  67.     }  
  68. }  
相关XML使用书写方式:
[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. <com.android.tomatotask.CircleProgressBar  
  2.     android:id="@+id/circleProgressbar" android:layout_width="300dp"  
  3.     android:layout_height="300dp" android:layout_centerInParent="true" />  
  4. <android.support.v4.view.ViewPager  
  5.     android:id="@+id/viewpage" android:layout_width="match_parent"  
  6.     android:layout_height="match_parent" />  

问题九:Animation动画效果的实现

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. protected Animation animation;  
[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. // 动画资源文件  
  2. ID = new int[] { R.anim.my_alpha_action, R.anim.my_scale_action,  
  3.         R.anim.my_rotate_action, R.anim.alpha_scale,  
  4.         R.anim.alpha_rotate, R.anim.scale_rotate,  
  5.         R.anim.alpha_scale_rotate, R.anim.myown_design };  
[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. animation = AnimationUtils.loadAnimation(MainActivity.this,  
  2.         ID[randow]);//randow为随机取到0~7的数的随机数  
  3. textView.startAnimation(animation);  

问题十:针对只有几个确定的数,使用SeekBar

打个比方,我只有10, 20, 30, 40, 50这几个数,我想使用SeekBar,最小值是10,最大值是50,如果我拖动进度条到95%的时候,刻度自动进到100% 即值为50的情况,那么在这种情况下我们该如何处理呢
请看下面的代码:
[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. private class SeekBarListener implements SeekBar.OnSeekBarChangeListener {  
  2.     private TextView textView;  
  3.     private int TickStep;  
  4.     private int StartTick;  
  5.     public SeekBarListener(TextView tv, int startTick, int tickStep) {  
  6.         textView = tv;  
  7.         TickStep = tickStep;  
  8.         StartTick = startTick;  
  9.     }  
  10.     @Override  
  11.     public void onProgressChanged(SeekBar seekBar, int progress,  
  12.             boolean fromUser) {  
  13.         // TODO Auto-generated method stub  
  14.         if (fromUser) {  
  15.             // ..  
  16.         }  
  17.         // 时间=process*步长+初始值  
  18.         // int progress=seekBar.getProgress();  
  19.         int curTick = progress + StartTick;  
  20.         int remainder = curTick % TickStep;  
  21.         int halfStep = TickStep % 2 == 0 ? TickStep - TickStep % 2  
  22.                 : TickStep - TickStep % 2 + 1;  
  23.         if (remainder < halfStep) {  
  24.             curTick -= remainder;  
  25.         } else {  
  26.             curTick += (TickStep - remainder);  
  27.         }  
  28.         // seekBar.setProgress(curTick - StartTick);  
  29.         textView.setText(curTick + "min");  
  30.     }  
  31.     @Override  
  32.     public void onStartTrackingTouch(SeekBar seekBar) {  
  33.         // TODO Auto-generated method stub  
  34.     }  
  35.     @Override  
  36.     public void onStopTrackingTouch(SeekBar seekBar) {  
  37.         // TODO Auto-generated method stub  
  38.         // 时间=process*步长+初始值  
  39.         int progress = seekBar.getProgress();  
  40.         int curTick = progress + StartTick;  
  41.         int remainder = curTick % TickStep;  
  42.         int halfStep = TickStep % 2 == 0 ? TickStep - TickStep % 2  
  43.                 : TickStep - TickStep % 2 + 1;  
  44.         if (remainder < halfStep) {  
  45.             curTick -= remainder;  
  46.         } else {  
  47.             curTick += (TickStep - remainder);  
  48.         }  
  49.         seekBar.setProgress(curTick - StartTick);  
  50.         textView.setText(curTick + "min");  
  51.     }  
  52. }  

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 华为手机返回键失灵怎么办 荣耀6p死机了怎么办 荣耀6主板烧坏了怎么办 虚拟运营商倒闭了号怎么办 买到二次放号怎么办 新运动鞋鞋穿着有点紧怎么办 一件代发被买家退货后怎么办? 洗了翻毛的鞋子怎么办 猫眼竹芋泡根了怎么办 双线花叶子卷了怎么办 华为云收藏满了怎么办 小米6云空间满了怎么办 华为云存储已满怎么办 苹果云备份空间不足怎么办 oppor9指纹与密码忘记怎么办 oppo显示密码格式不对怎么办 oppo云服务密码忘了怎么办 小米云内存满了怎么办 id储存空间满了怎么办 苹果手机邮箱服务器连接失败怎么办 苹果查看id闪退怎么办 域名卖出去后涉及赌博怎么办 发票认证后对方作废了怎么办 手机在屋里没信号怎么办 百度云上传文件和谐怎么办 收货地址写错了怎么办 阿里巴巴国际版出现加密令牌怎么办 淘宝寄货到转运仓拒收怎么办 淘宝已发货买家申请退货怎么办 买家给了一个差评不接电话怎么办 卖家单号填错了怎么办 拼多多虚假发货买家怎么办 买家退款后又收到货怎么办 买家确认收货已超时怎么办 淘宝买家不确认收货怎么办 买家快递单号填错怎么办 买家不确认收货不评价怎么办 淘宝不给改地址怎么办 淘宝快递发货后申请退款怎么办 摄影公司收钱后跑了怎么办 淘宝上申请退款卖家不处理怎么办