Android學習之——APP番茄工作法——小結(1)

來源:互聯網
上載者:User

今天,我的第一個APP:番茄工作法 1.0版本終於終於終於完成了,雖然還有很多很多的不足之處,但是,終歸算是告一個段落了。第一款小應用,其中的艱辛冷暖自知,各種摸爬滾打,各種度娘Google。簡單講解下其中碰到的問題:
問題一:android.support.v4.app.Fragment 包下沒有PreferenceFragment的問題。起初做的設定介面太過難看,所以打算使用Google力推的片段機制,但是發現v4包下面居然沒有PreferenceFragment類。然後各種搞不定。最後在Google的協助下順利找到實現方法(花了我將近一個禮拜的時間,淚奔,新手不解釋...)https://github.com/kolavar/android-support-v4-preferencefragment進入上面的連結下載這個library。實現方式和android.preference.PreferenceFragment 下的方式一樣,具體代碼如下:
public class fragment3 extends PreferenceFragment{    public static fragment3 newInstance(Bundle bundle) {        fragment3 frag = new fragment3();        frag.setArguments(bundle);        return frag;    }    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        addPreferencesFromResource(R.xml.preferences);          Log.v("huahua", "fragment3-->onCreate()");    }}
具體代碼我會在下面全部放出來其中有一點不足,相當遺憾: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中去,具體的使用代碼如下:
SharedPreferences mySharedPreferences = getActivity().getSharedPreferences("TomatoCount",        Activity.MODE_PRIVATE);//擷取SharedPreferences 中的值,TomatoCount表示儲存的檔案名稱String dateStr = mySharedPreferences.getString("date", "2001-01-01");//擷取字串todayTomatoCount = mySharedPreferences.getInt("todayTomatoCount", 0);//擷取儲存的今日番茄時間,擷取int型資料,如果不存在預設設定為0allTomatoCount = mySharedPreferences.getInt("allTomatoCount", 0);//擷取儲存的合計番茄時間String dateNowString = (new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())).format(new java.util.Date());if (!dateStr.equals(dateNowString)) {//判斷儲存時間是否和目前時間在同一天    todayTomatoCount=0;    SharedPreferences.Editor editor = mySharedPreferences.edit();    editor.putInt("todayTomatoCount", todayTomatoCount);//寫入資料到Editor 其中第一個參數是欄位的名稱,第二個參數是欄位的值,該寫入的是int類型    editor.commit();//提交,寫入到xml檔案中}

問題三:修改字型在assets檔案夾下建立fonts檔案夾,將需要的字型(*.ttf)放入到該檔案夾下,代碼中使用該字型的方法如下:
//修改字型Typeface fontFace = Typeface.createFromAsset(getActivity().getAssets(), "fonts/Roboto-Thin.ttf");tomatoTxtView.setTypeface(fontFace);

問題四:如何在PreferenceFragment實作類別中如果要即時的擷取修改的值等如果當ListPreference中的值改變以後,我要在ListPreference的副標題中顯示改變的值該如何操作呢:重寫onSharedPreferenceChanged方法如果當我們需要點擊preference進入到另外一個頁面時,或者我們需要跳轉到網頁時,該如何操作呢:重寫onPreferenceTreeClick方法
public class SettingPreferenceFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener {    ListPreference lstPre_TomatoTime_value, lstPre_BreakTime_value;    public SettingPreferenceFragment() {        // TODO 自動產生的建構函式存根    }    @Override    public void onCreate(Bundle paramBundle) {        // TODO 自動產生的方法存根        super.onCreate(paramBundle);        addPreferencesFromResource(R.xml.preferences);        SharedPreferences prefs=PreferenceManager.getDefaultSharedPreferences(getActivity());        prefs.registerOnSharedPreferenceChangeListener(this);        lstPre_TomatoTime_value=(ListPreference)findPreference("TomatoTime_value");        lstPre_BreakTime_value=(ListPreference)findPreference("BreakTime_value");        lstPre_TomatoTime_value.setSummary(lstPre_TomatoTime_value.getEntry());        lstPre_BreakTime_value.setSummary(lstPre_BreakTime_value.getEntry());    }    @Override    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,            String key) {        // TODO 自動產生的方法存根        if (key.equals("TomatoTime_value")) {            lstPre_TomatoTime_value.setSummary(lstPre_TomatoTime_value.getEntry());        }        if (key.equals("BreakTime_value")) {            lstPre_BreakTime_value.setSummary(lstPre_BreakTime_value.getEntry());        }    }         @Override    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,            Preference preference) {        // TODO 自動產生的方法存根        if (preference.getKey().equals("clearCount")) {            alertDialogShow();        }        if (preference.getKey().equals("aboutTomatoTask")) {            Uri uri = Uri.parse("http://baike.baidu.com/link?url=b7rlhS6YssFup2xqAjnw9__6VsQnyhtVT8Gx_-qwckUE4IZ-ns6i_jw9w_aKH-C_sjWheb9NFR_GZcfUII0bV_");            startActivity(new Intent(Intent.ACTION_VIEW,uri));        }        return false;    }         /**     * 顯示AlertDialog     */    private void alertDialogShow() {        new AlertDialog.Builder(getActivity()).setTitle("清除?").setMessage("是否清除計數?\n註:該操作無法復原!").setPositiveButton("清除", new DialogInterface.OnClickListener() {                         @Override            public void onClick(DialogInterface dialog, int which) {                // TODO 自動產生的方法存根                SharedPreferences mySharedPreferences = getActivity().getSharedPreferences("TomatoCount",                        Activity.MODE_PRIVATE);                SharedPreferences.Editor editor = mySharedPreferences.edit();                editor.putInt("todayTomatoCount", 0);                editor.putInt("allTomatoCount", 0);                editor.commit();                Toast.makeText(getActivity(), "清除成功!", Toast.LENGTH_SHORT).show();            }        }).setNegativeButton("取消", new DialogInterface.OnClickListener() {            @Override            public void onClick(DialogInterface dialog, int which) {                // TODO 自動產生的方法存根            }        }).create().show();    }}

問題五:如何?倒計時
在android 已經給我們封裝好了一個倒計時的類,我們直接拿來實現就可以啦,具體過程如下:
private TimeCount time;
2. new 一個TimeCount, timeSpan是需要倒計時的時間(毫秒),1000是倒計時間隔,這裡是一秒
time = new TimeCount(timeSpan, 1000);// 構造CountDownTimer對象time.start();
3. 寫內部類TimeCount 繼承自CountDownTimer 其中onTick表示,在上述設定的倒計時間隔期間做什麼,onFinish表示計時完畢時做什麼
class TimeCount extends CountDownTimer {    public TimeCount(long millisInFuture, long countDownInterval) {        super(millisInFuture, countDownInterval);// 參數依次為總時間長度,和計時的時間間隔    }    /**     * 計時過程顯示     */    @Override    public void onTick(long millisUntilFinished) {        // TODO 自動產生的方法存根    }    /**     * 計時完畢時觸發     */    @Override    public void onFinish() {        // TODO 自動產生的方法存根    }}

問題六:觸發點擊事件:當我們點擊返回按鍵時,是否彈出AlertDialog提示框,或者是提示“再按一次退出”的實現:

@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {    if (flag == 2) {        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {            AlertDialog.Builder alertBuilder = new AlertDialog.Builder(                    MainActivity.this);            alertBuilder                    .setTitle("放棄?")                    .setMessage("是否放棄這個番茄並退出嗎?")                    .setPositiveButton("確定",                            new DialogInterface.OnClickListener() {                                 @Override                                public void onClick(DialogInterface dialog,                                        int which) {                                    // TODO 自動產生的方法存根                                    time.cancel();                                    MainActivity.this.finish();                                }                            })                    .setNegativeButton("取消",                            new DialogInterface.OnClickListener() {                                 @Override                                public void onClick(DialogInterface dialog,                                        int which) {                                    // TODO 自動產生的方法存根                                    dialog.cancel();                                }                            }).create();            alertBuilder.show();        }    } else {        if (keyCode == KeyEvent.KEYCODE_BACK                && event.getAction() == KeyEvent.ACTION_DOWN) {            if ((System.currentTimeMillis() - exitTime) > 2000) {                Toast.makeText(getApplicationContext(), "再按一次退到主介面",                        Toast.LENGTH_SHORT).show();                exitTime = System.currentTimeMillis();            } else {                time.cancel();                finish();                System.exit(0);            }            return true;        }        return super.onKeyDown(keyCode, event);    }    return true;}

問題七:震動的實現

private Vibrator vibrator;
//開啟震動vibrator =(Vibrator)getSystemService(Context.VIBRATOR_SERVICE);long [] pattern = {200,500,200,500,1200,500,200,500};   // 停止 開啟 停止 開啟  vibrator.vibrate(pattern,-1);           //重複兩次上面的pattern 如果只想震動一次,index設為-1 

問題八:重寫ProgressBar,設定為圓形進度條:

來源:http://www.pocketdigi.com/20130712/1136.html
package com.android.tomatotask;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.RectF;import android.util.AttributeSet;import android.view.View;public class CircleProgressBar extends View {    private int maxProgress = 10;//最大進度    private int progress = 0;//當前進度    private int progressStrokeWidth = 6;//線寬    // 畫圓所在的矩形地區    RectF oval;    Paint paint;    public CircleProgressBar(Context context) {        super(context);        // TODO 自動產生的建構函式存根    }    public CircleProgressBar(Context context, AttributeSet attrs) {        super(context, attrs);        // TODO 自動產生的建構函式存根        oval = new RectF();        paint = new Paint();    }    public CircleProgressBar(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        // TODO 自動產生的建構函式存根    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);           /**         * 畫最外層的大圓環         */        int centre = getWidth()/2; //擷取圓心的x座標        int radius = (int) (centre - progressStrokeWidth/2); //圓環的半徑        paint.setColor(Color.WHITE);//(roundColor); //設定圓環的顏色        paint.setStyle(Paint.Style.STROKE); //設定空心        paint.setStrokeWidth(progressStrokeWidth); //設定圓環的寬度        paint.setAntiAlias(true);  //消除鋸齒         canvas.drawCircle(centre, centre, radius, paint); //畫出圓環                /**         * 畫圓弧 ,畫圓環的進度         */               //設定進度是實心還是空心        paint.setStrokeWidth(progressStrokeWidth); //設定圓環的寬度        paint.setColor(Color.rgb(0x57, 0x87, 0xb6));  //設定進度的顏色         RectF oval = new RectF(centre - radius, centre - radius, centre                + radius, centre + radius);  //用於定義的圓弧的形狀和大小的界限            paint.setStyle(Paint.Style.STROKE);            canvas.drawArc(oval, -90, 360 * progress / maxProgress, false, paint);  //根據進度畫圓弧  繪製白色圓圈,即進度條背景    }       public int getMaxProgress(){        return maxProgress;    }       public void setMaxProgress(int maxProgress){        this.maxProgress = maxProgress;    }       public void setProgress(int progress){        this.progress = progress;        this.invalidate();    }       public void setProgressNotInUiThread(int progress){        this.progress = progress;        this.postInvalidate();    }}
相關XML使用書寫方式:
<com.android.tomatotask.CircleProgressBar    android:id="@+id/circleProgressbar" android:layout_width="300dp"    android:layout_height="300dp" android:layout_centerInParent="true" /><android.support.v4.view.ViewPager    android:id="@+id/viewpage" android:layout_width="match_parent"    android:layout_height="match_parent" />

問題九:Animation動畫效果的實現

protected Animation animation;
// 動畫資源檔案ID = new int[] { R.anim.my_alpha_action, R.anim.my_scale_action,        R.anim.my_rotate_action, R.anim.alpha_scale,        R.anim.alpha_rotate, R.anim.scale_rotate,        R.anim.alpha_scale_rotate, R.anim.myown_design };
animation = AnimationUtils.loadAnimation(MainActivity.this,        ID[randow]);//randow為隨機取到0~7的數的隨機數textView.startAnimation(animation);

問題十:針對只有幾個確定的數,使用 SeekBar

打個比方,我只有10, 20, 30, 40, 50這幾個數,我想使用SeekBar,最小值是10,最大值是50,如果我拖動進度條到95%的時候,刻度自動進到100% 即值為50的情況,那麼在這種情況下我們該如何處理呢請看下面的代碼:
private class SeekBarListener implements SeekBar.OnSeekBarChangeListener {    private TextView textView;    private int TickStep;    private int StartTick;    public SeekBarListener(TextView tv, int startTick, int tickStep) {        textView = tv;        TickStep = tickStep;        StartTick = startTick;    }    @Override    public void onProgressChanged(SeekBar seekBar, int progress,            boolean fromUser) {        // TODO Auto-generated method stub        if (fromUser) {            // ..        }        // 時間=process*步長+初始值        // int progress=seekBar.getProgress();        int curTick = progress + StartTick;        int remainder = curTick % TickStep;        int halfStep = TickStep % 2 == 0 ? TickStep - TickStep % 2                : TickStep - TickStep % 2 + 1;        if (remainder < halfStep) {            curTick -= remainder;        } else {            curTick += (TickStep - remainder);        }        // seekBar.setProgress(curTick - StartTick);        textView.setText(curTick + "min");    }    @Override    public void onStartTrackingTouch(SeekBar seekBar) {        // TODO Auto-generated method stub    }    @Override    public void onStopTrackingTouch(SeekBar seekBar) {        // TODO Auto-generated method stub        // 時間=process*步長+初始值        int progress = seekBar.getProgress();        int curTick = progress + StartTick;        int remainder = curTick % TickStep;        int halfStep = TickStep % 2 == 0 ? TickStep - TickStep % 2                : TickStep - TickStep % 2 + 1;        if (remainder < halfStep) {            curTick -= remainder;        } else {            curTick += (TickStep - remainder);        }        seekBar.setProgress(curTick - StartTick);        textView.setText(curTick + "min");    }}





問題一的相關代碼下載:http://download.csdn.net/detail/fu222cs98/7026253
番茄工作法APK下載:http://pan.baidu.com/s/1jGC4fXG 註:原始碼已分享在GitHub上

Android學習之——APP番茄工作法——小結(2):http://blog.csdn.net/fu222cs98/article/details/21056435






聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.