zoukankan      html  css  js  c++  java
  • Android之收音机UI实现(转)

    源码:

    http://www.2cto.com/kf/201211/171417.html

    最近在研究收音机的源码,本来想把收音机从源码中提取出来,做成一个单独的应用,但是,收音机需要底层的支持,所以,就有点无能为力了,不过发现UI做得比较有个性(如下图所示),图片比较丑(这是做图片MM的责任哦,哈哈),就单独拿出来跟大家分享一下,顺便自己也学习一下自定义view。

     今天我们主要实现的是中间红色区域的部分,下面我们来看一下它的布局文件radio.xml,它最外围是一个绝对布局,其实我个人是比较反对用绝对布局的,用其他布局也绝对能解决这个问题,大不了可以把图片资源分割一下吗,可见做这个应用的公司做美工的MM是何等的奇缺啊!O(∩_∩)O哈哈~(可怜的程序猿,又少了一个跟MM相处的机会了)。
    <?xml version="1.0" encoding="utf-8"?> 
    <AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android" 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" 
        android:background="@drawable/background_main" 
        android:orientation="vertical" > 
     
        <RelativeLayout  www.2cto.com
            android:layout_width="320dip" 
            android:layout_height="113dip" 
            android:layout_x="0dip" 
            android:layout_y="180dip" 
            android:background="@drawable/led_disabled" /> 
     
        <RelativeLayout 
            android:id="@+id/led_background" 
            android:layout_width="320dip" 
            android:layout_height="113dip" 
            android:layout_x="0dip" 
            android:layout_y="180dip" 
            android:background="@drawable/led_enabled" > 
     
            <ImageView 
                android:id="@+id/fm_indicator" 
                android:layout_width="wrap_content" 
                android:layout_height="wrap_content" 
                android:layout_alignParentLeft="true" 
                android:layout_alignParentTop="true" 
                android:layout_marginLeft="14dip" 
                android:layout_marginTop="12dip" 
                android:src="@drawable/fm" /> 
     
            <ImageView 
                android:id="@+id/headset_indicator" 
                android:layout_width="wrap_content" 
                android:layout_height="wrap_content" 
                android:layout_marginTop="12dip" 
                android:layout_toRightOf="@id/fm_indicator" 
                android:src="@drawable/headset_indicator" /> 
     
            <TextView 
                android:id="@+id/text_hour_type" 
                android:layout_width="wrap_content" 
                android:layout_height="wrap_content" 
                android:layout_alignParentRight="true" 
                android:layout_alignParentTop="true" 
                android:layout_marginRight="13dip" 
                android:layout_marginTop="10dip" 
                android:textColor="#000000" /> 
     
            <com.way.view.DigitalTextView 
                android:id="@+id/digital_clock" 
                android:layout_width="wrap_content" 
                android:layout_height="wrap_content" 
                android:layout_alignParentTop="true" 
                android:layout_marginTop="13dip" 
                android:layout_toLeftOf="@+id/text_hour_type" /> 
     
            <ImageView 
                android:id="@+id/searching_indicator" 
                android:layout_width="wrap_content" 
                android:layout_height="wrap_content" 
                android:layout_marginTop="13dip" 
                android:layout_toLeftOf="@id/digital_clock" 
                android:src="@drawable/searching" /> 
     
            <com.way.view.DigitalTextView 
                android:id="@+id/digital_freq" 
                android:layout_width="wrap_content" 
                android:layout_height="wrap_content" 
                android:layout_alignParentRight="true" 
                android:layout_alignParentTop="true" 
                android:layout_marginRight="84dip" 
                android:layout_marginTop="15dip" /> 
     
            <SeekBar 
                android:id="@+id/freq_indicator" 
                android:layout_width="fill_parent" 
                android:layout_height="wrap_content" 
                android:layout_alignParentBottom="true" 
                android:layout_marginBottom="12dip" 
                android:layout_marginLeft="7dip" 
                android:layout_marginRight="7dip" 
                android:progressDrawable="@drawable/blank" 
                android:thumb="@drawable/pointer" 
                android:thumbOffset="0dip" /> 
        </RelativeLayout> 
     
        <FrameLayout 
            android:layout_width="220dip" 
            android:layout_height="30dip" 
            android:layout_x="50dip" 
            android:layout_y="291dip" 
            android:background="@drawable/scroller_bg" > 
     
            <com.way.view.TuneWheel 
                android:id="@+id/tune_wheel" 
                android:layout_width="fill_parent" 
                android:layout_height="fill_parent" /> 
     
            <ImageView 
                android:layout_width="fill_parent" 
                android:layout_height="fill_parent" 
                android:src="@drawable/tune_wheel_highlight" /> 
        </FrameLayout> 
     
        <ImageButton 
            android:id="@+id/add_button" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:layout_x="39dip" 
            android:layout_y="332dip" 
            android:background="#00000000" 
            android:src="@drawable/add_button" /> 
     
        <ImageButton 
            android:id="@+id/prev_station_button" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:layout_x="108dip" 
            android:layout_y="332dip" 
            android:background="#00000000" 
            android:src="@drawable/prev_station_button" /> 
     
        <ImageButton 
            android:id="@+id/search_prev_button" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:layout_x="176dip" 
            android:layout_y="332dip" 
            android:background="#00000000" 
            android:src="@drawable/search_prev_button" /> 
     
        <com.way.view.CheckableImageButton 
            android:id="@+id/headset_toggle" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:layout_x="255dip" 
            android:layout_y="332dip" 
            android:background="#00000000" /> 
     
        <com.way.view.CheckableImageButton 
            android:id="@+id/power_toggle" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:layout_x="0dip" 
            android:layout_y="403dip" 
            android:background="#00000000" /> 
     
        <ImageButton 
            android:id="@+id/radio_list_button" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:layout_x="80dip" 
            android:layout_y="402dip" 
            android:background="#00000000" 
            android:src="@drawable/radio_list_button" /> 
     
        <ImageButton 
            android:id="@+id/next_station_button" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:layout_x="146dip" 
            android:layout_y="404dip" 
            android:background="#00000000" 
            android:src="@drawable/next_station_button" /> 
     
        <ImageButton 
            android:id="@+id/search_next_button" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:layout_x="215dip" 
            android:layout_y="402dip" 
            android:background="#00000000" 
            android:src="@drawable/search_next_button" /> 
     
    </AbsoluteLayout> 

    接下来让我们来看一下那个自定义滚轮的代码TuneWheel:
    /**
     * 调频的滚轮
     * 
     * @author way
     * 
     */ 
    public class TuneWheel extends View { 
        /**
         * 滚轮滚动监听接口
         */ 
        public interface OnTuneWheelValueChangedListener { 
            public void onTuneWheelValueChanged(View v, float changedBy); 
        } 
     
        private static final String TAG = "TuneWheel"; 
        private static final int LINE_SPAN = 8;//线性跨度 
        private static final int DRAG_THRESHOLD = 5;//滚动的最小阈值,即在屏幕x轴上至少滑动5个坐标点才有效 
        private static final float CHANGE_THRESHOLD = 0.1f;//最小的改变阈值,即需要传递出去的那个值的最小值 
        public static final int DIRECTION_PREV = 1;//向左滚动的方向值 
        public static final int DIRECTION_NEXT = 2;//向右滚动的方向值 
     
        private boolean mIsMoving = false;// 是否在滑动 
        private float mLastDragPos;//最终的滚动位置 
        private float mCurrentPos = 0;// 当前位置 
        private float mCurrentChange = 0;// 当前改变值 
        private int mDragEnable = DIRECTION_PREV | DIRECTION_NEXT; 
     
        private OnTuneWheelValueChangedListener mListener = null;// 监听接口对象 
     
        public void setOnValueChangedListener( 
                OnTuneWheelValueChangedListener listener) {// 提供监听方法 
            mListener = listener; 
        } 
     
        /**
         * 根据传入的方向设置是否允许滚动
         * 
         * @param direction
         *            传入的方向
         * @param enable
         *            是否能滚动
         */ 
        public void setDragEnable(int direction, boolean enable) { 
            if (enable) { 
                mDragEnable = mDragEnable | direction; 
            } else { 
                mDragEnable = mDragEnable ^ direction; 
            } 
        } 
     
        /**
         * 根据输入的方向判断是否允许滚动
         * 
         * @param direction
         *            传入的方向
         * @return 是否能滚动
         */ 
        public boolean getDragEnable(int direction) { 
            return (mDragEnable & direction) != 0; 
        } 
     
        // 三个构造器 
        public TuneWheel(Context context) { 
            super(context); 
        } 
     
        public TuneWheel(Context context, AttributeSet attrs) { 
            super(context, attrs); 
        } 
     
        public TuneWheel(Context context, AttributeSet attrs, int defStyle) { 
            super(context, attrs, defStyle); 
        } 
     
        // 重写onDraw方法 
        protected void onDraw(Canvas canvas) { 
            Paint mLinePaint = new Paint(); 
            mLinePaint.setARGB(0xEC, 0x00, 0, 0); 
            mLinePaint.setStrokeWidth(0.5f); 
            for (int pos = 0; pos + mCurrentPos < getWidth(); pos += LINE_SPAN) { 
                canvas.drawLine(pos + mCurrentPos, 0, pos + mCurrentPos, 
                        getHeight(), mLinePaint); 
            } 
        } 
     
        // 重写onTouchEvent方法,实现滚动效果 
        public boolean onTouchEvent(MotionEvent event) { 
            if (!this.isEnabled()) 
                return false; 
     
            int action = event.getAction(); 
     
            switch (action) { 
            case MotionEvent.ACTION_DOWN://按下 
                mLastDragPos = event.getX();//获取按下时的x轴坐标值,滚轮只能左右滑动,所以只要获取x值即可 
                break; 
            case MotionEvent.ACTION_MOVE://移动 
                float currentDragPos = event.getX(); 
     
                if (!getDragEnable(getDirection(currentDragPos, mLastDragPos)))//如果当前方向不允许滚动 
                    return false; 
     
                if (!mIsMoving) {//如果当前状态为没有滚动 
                    if (Math.abs(currentDragPos - mLastDragPos) > DRAG_THRESHOLD) {//如果滚动范围大于最小阈值 
                        mIsMoving = true; 
                        mLastDragPos = currentDragPos; 
                    } else { 
                        return false; 
                    } 
                } else {//如果当前状态为一直在滚动 
                    float tempPos = (mCurrentPos + currentDragPos - mLastDragPos) 
                            % LINE_SPAN;//保存一个临时变化值 
     
                    mCurrentChange += calculateChange(currentDragPos, mLastDragPos); 
                    if (Math.abs(mCurrentChange) > CHANGE_THRESHOLD) { 
                        if (mListener != null) { 
                            mListener.onTuneWheelValueChanged(this, mCurrentChange);//将滚动变化值通过监听接口传递出去 
                        } 
                        mCurrentChange = 0; 
                    } 
     
                    mCurrentPos = tempPos; 
                    invalidate();//千万要记得刷新一下界面 
                    mLastDragPos = currentDragPos; 
                } 
                break; 
            case MotionEvent.ACTION_UP://松开 
                if (mIsMoving) { 
                    mIsMoving = false;//松开后更新状态为停止滚动0. 
                } 
                break; 
            } 
     
            return true; 
        } 
     
        /**
         * 根据改变计算滚动方向
         * 
         * @param current
         *            当前位置值
         * @param last
         *            最终位置值
         * @return 方向值
         */ 
        private int getDirection(float current, float last) { 
            return (int) (Math.signum(current - last) + 3) / 2; 
        } 
     
        /**
         * 根据改变计算改变值
         * 
         * @param current
         *            当前位置值
         * @param last
         *            最终位置值
         * @return 改变值
         */ 
        private float calculateChange(float current, float last) { 
            float sub = current - last; 
            return Math.signum(sub) * (float) Math.pow(Math.abs(sub), 1.3) / 100; 
        } 


    第三,是中间那个显示时间和调频自定义的View,DigitalTextView.java:
    /**
     * 自定义的一个显示调频或时间的view
     * 
     * @author way
     * 
     */ 
    public class DigitalTextView extends LinearLayout { 
     
        private static final String TAG = "DigitalTextView"; 
        private String mResourcePrefix = "";// 资源前缀,时间或调频 
     
        // 两个构造器,自定义view中至少要有2个构造器 
        public DigitalTextView(Context context) { 
            super(context); 
            init(); 
        } 
     
        public DigitalTextView(Context context, AttributeSet attrs) { 
            super(context, attrs); 
            init(); 
        } 
     
        // 初始化 
        private void init() { 
            this.setOrientation(LinearLayout.HORIZONTAL); 
        } 
     
        /**
         * 获取对应的时间图片
         * 
         * @param index
         *            时间值
         * @return 对应的时间图片id
         */ 
        private int getTimeDrawable(int index) { 
            int drawableId = -1; 
            switch (index) { 
            case 0: 
                drawableId = R.drawable.time_0; 
                break; 
            case 1: 
                drawableId = R.drawable.time_1; 
                break; 
            case 2: 
                drawableId = R.drawable.time_2; 
                break; 
            case 3: 
                drawableId = R.drawable.time_3; 
                break; 
            case 4: 
                drawableId = R.drawable.time_4; 
                break; 
            case 5: 
                drawableId = R.drawable.time_5; 
                break; 
            case 6: 
                drawableId = R.drawable.time_6; 
                break; 
            case 7: 
                drawableId = R.drawable.time_7; 
                break; 
            case 8: 
                drawableId = R.drawable.time_8; 
                break; 
            case 9: 
                drawableId = R.drawable.time_9; 
                break; 
            } 
            return drawableId; 
        } 
     
        /**
         * 获取调频图片
         * 
         * @param index
         *            频率值
         * @return 对应频率值的图片id
         */ 
        private int getFreqDrawable(int index) { 
            int drawableId = -1; 
            switch (index) { 
            case 0: 
                drawableId = R.drawable.freq_0; 
                break; 
            case 1: 
                drawableId = R.drawable.freq_1; 
                break; 
            case 2: 
                drawableId = R.drawable.freq_2; 
                break; 
            case 3: 
                drawableId = R.drawable.freq_3; 
                break; 
            case 4: 
                drawableId = R.drawable.freq_4; 
                break; 
            case 5: 
                drawableId = R.drawable.freq_5; 
                break; 
            case 6: 
                drawableId = R.drawable.freq_6; 
                break; 
            case 7: 
                drawableId = R.drawable.freq_7; 
                break; 
            case 8: 
                drawableId = R.drawable.freq_8; 
                break; 
            case 9: 
                drawableId = R.drawable.freq_9; 
                break; 
            } 
            return drawableId; 
        } 
     
        /**
         * 根据传递进来的字符,返回对应的图片资源
         * 
         * @param c
         *            传递进来的字符
         * @return 对应的图片id
         */ 
        private int getResourceForChar(char c) { 
            if (c == '.') { 
                if (!mResourcePrefix.equals("time")) { 
                    return R.drawable.freq_dot; 
                } 
            } else if (c == ':') { 
                if (mResourcePrefix.equals("time")) { 
                    return R.drawable.time_colon; 
                } 
            } else if (c >= '0' && c <= '9') { 
                if (mResourcePrefix.equals("time")) { 
                    return getTimeDrawable(c - '0'); 
                } else { 
                    return getFreqDrawable(c - '0'); 
                } 
            } else { 
                return -1; 
            } 
            return -1; 
        } 
     
        // 创建一个ImageView 
        private ImageView createImageView() { 
            ImageView imageView = new ImageView(getContext()); 
            LayoutParams param = new LayoutParams( 
                    LinearLayout.LayoutParams.WRAP_CONTENT, 
                    LinearLayout.LayoutParams.WRAP_CONTENT); 
            imageView.setLayoutParams(param); 
            return imageView; 
        } 
     
        /**
         * 设置资源前缀,是时间还是调频
         * 
         * @param resourcePrefix
         */ 
        public void setResourcePrefix(String resourcePrefix) { 
            mResourcePrefix = resourcePrefix; 
        } 
     
        /**
         * 设置数字值,类似TextView的setText()
         * 
         * @param text
         *            传递进来的字符串
         */ 
        public void setDigitalText(String text) { 
            updateView(text); 
        } 
     
        /**
         * 更新自定义TextView
         * 
         * @param text
         *            传递进来的字符串
         */ 
        private void updateView(String text) { 
     
            int startIndex = getChildCount() - text.length();// 起始位置,因为imageView的数量是根据字符串的长度创建的 
            if (startIndex < 0)//第一次更新的时候肯定是小于0的 
                startIndex = 0; 
     
            for (int i = 0; i < startIndex; i++) { 
                getChildAt(i).setVisibility(View.GONE);//把之前的图片隐藏起来,个人感觉这样做得不怎么样 
            } 
     
            //下面是根据字符串的长度,循环更换为对应的图片 
            for (int i = 0; i < text.length(); i++) { 
                int childId = i + startIndex; 
                int resId = getResourceForChar(text.charAt(i));//将每个字符转换为数字 
     
                if (resId != -1) { 
                    if (childId == getChildCount()) { 
                        addView(createImageView());//添加到LinearLayout中 
                    } 
                    ImageView child = ((ImageView) getChildAt(childId)); 
                    child.setVisibility(View.VISIBLE); 
                    child.setImageResource(resId); 
                } 
            } 
        } 

    最后,就是把这些自定义View综合起来的MainActivity了:
    public class Main extends Activity implements OnTuneWheelValueChangedListener { 
        private static final int FREQ_POINTER_SCALE = 10; 
        private TuneWheel mTuneWheel;// 滚轮 
        private DigitalTextView mFreqView;// 显示调频波段的view 
        private SeekBar mFreqPointer;// 进度条指针 
        private TextView mClockType;// 显示时间的格式pm、am 
        private DigitalTextView mDigitalClock;// 显示时间的view 
        private String mClockTypeString;// 时间 
        private View mSearchingIndicator;// 加载时间的时候刷新图标 
        private CheckableImageButton mPowerToggle, mHeadsetToggle;// 开关键和耳机扬声器切换键 
        private DigitalClockUpdater mDigitalClockUpdater;// 更新时间的对象 
        private float channel = 87.5f;// 默认初始的波段 
     
        @Override 
        protected void onCreate(Bundle savedInstanceState) { 
            super.onCreate(savedInstanceState); 
            setContentView(R.layout.radio); 
            initView();// 初始化view 
        } 
     
        private void initView() { 
            // 开关键 
            mPowerToggle = (CheckableImageButton) findViewById(R.id.power_toggle); 
            mPowerToggle.setDrawable(R.drawable.power_button_checked, 
                    R.drawable.power_button_unchecked, 
                    R.drawable.power_button_disabled); 
            // 耳机扬声器切换键 
            mHeadsetToggle = (CheckableImageButton) findViewById(R.id.headset_toggle); 
            mHeadsetToggle.setDrawable(R.drawable.headset_button_checked, 
                    R.drawable.headset_button_unchecked, 
                    R.drawable.headset_button_disabled); 
     
            mClockType = (TextView) findViewById(R.id.text_hour_type);// 时间类型 
            Date curDate = new Date(java.lang.System.currentTimeMillis()); 
            int hours = curDate.getHours(); 
            if (!DateFormat.is24HourFormat(Main.this)) {// 如果不是24小时制 
                if (hours > 12) { 
                    mClockTypeString = getString(R.string.pm); 
                } else { 
                    mClockTypeString = getString(R.string.am); 
                } 
                mClockType.setText(mClockTypeString);// 设置pm、am格式 
            } else { 
                mClockType.setText("");// 如果所24小时制,就不要任何标识 
            } 
            mDigitalClock = (DigitalTextView) findViewById(R.id.digital_clock); 
            mDigitalClock.setResourcePrefix("time"); 
            mDigitalClockUpdater = new DigitalClockUpdater(mDigitalClock); 
            mDigitalClockUpdater.run();// 启动更新时间 
     
            mTuneWheel = (TuneWheel) findViewById(R.id.tune_wheel);// 滚轮 
            mTuneWheel.setOnValueChangedListener(this);// 监听滚动事件 
     
            // 显示波段的view 
            mFreqView = (DigitalTextView) findViewById(R.id.digital_freq); 
            mFreqView.setResourcePrefix("freq"); 
            mFreqView.setDigitalText(String.valueOf(channel));// 初始化为默认值,实际从配置文件中读取上次保存的频段 
     
            mSearchingIndicator = findViewById(R.id.searching_indicator); 
            mSearchingIndicator.setVisibility(View.INVISIBLE);// 加载完时间后,自动隐藏这个图标 
     
            // 频段进度条 
            mFreqPointer = (SeekBar) findViewById(R.id.freq_indicator); 
            // 设置进度条范围 
            mFreqPointer 
                    .setMax((int) ((WheelConfig.RADIO_MAX_FREQUENCY - WheelConfig.RADIO_MIN_FREQUENCY) * FREQ_POINTER_SCALE)); 
            mFreqPointer.setEnabled(false); 
        } 
     
        @Override 
        public void onTuneWheelValueChanged(View v, float changedBy) {// 滚轮滑动监听事件 
            // TODO Auto-generated method stub 
            float freq = adjustFreq(WheelConfig.format(channel + changedBy));// 调整滚轮滑动变化值 
            channel = freq;// 用一个全局变量保存一下当前的调频 
            setFreqForUi(freq);// 更新ui 
        } 
     
        /**
         * 调整和限制滚轮滑动的值
         * 
         * @param freq
         *            需要调整的值
         * @return 调整后的值
         */ 
        private float adjustFreq(float freq) { 
            float result = ((int) (freq * 10)) / 10f; 
            if (result < WheelConfig.RADIO_MIN_FREQUENCY) 
                result = WheelConfig.RADIO_MIN_FREQUENCY; 
     
            if (result > WheelConfig.RADIO_MAX_FREQUENCY) 
                result = WheelConfig.RADIO_MAX_FREQUENCY; 
            return result; 
        } 
     
        /**
         * 通过传入的滚轮值,更新ui
         * 
         * @param freq
         *            调整后的滚轮值
         */ 
        private void setFreqForUi(float freq) { 
            if (freq == WheelConfig.RADIO_MIN_FREQUENCY) { 
                mTuneWheel.setDragEnable(TuneWheel.DIRECTION_PREV, false); 
                mTuneWheel.setDragEnable(TuneWheel.DIRECTION_NEXT, true); 
            } else if (freq == WheelConfig.RADIO_MAX_FREQUENCY) { 
                mTuneWheel.setDragEnable(TuneWheel.DIRECTION_PREV, true); 
                mTuneWheel.setDragEnable(TuneWheel.DIRECTION_NEXT, false); 
            } else { 
                mTuneWheel.setDragEnable(TuneWheel.DIRECTION_PREV, true); 
                mTuneWheel.setDragEnable(TuneWheel.DIRECTION_NEXT, true); 
            } 
            // 更新进度条位置 
            mFreqPointer 
                    .setProgress((int) ((freq - WheelConfig.RADIO_MIN_FREQUENCY) * FREQ_POINTER_SCALE)); 
            mFreqView.setDigitalText(String.valueOf(freq));// 更新当前频段值 
        } 
     
        @Override 
        protected void onDestroy() { 
            super.onDestroy(); 
            mDigitalClockUpdater.stop();// 停止更新时间 
        } 
     
        /**
         * 更新时间的类
         * 
         * @author way
         * 
         */ 
        private class DigitalClockUpdater { 
            private static final int MSG_UPDATE_TIME = 0x001; 
            private static final int UPDATE_INTERNAL = 1000; 
            DigitalTextView mView = null; 
     
            boolean mRunning = false; 
     
            Handler mUpdateHandler = new Handler() { 
                @Override 
                public void handleMessage(Message msg) { 
                    if (msg.what == MSG_UPDATE_TIME) { 
                        Date curDate = new Date( 
                                java.lang.System.currentTimeMillis()); 
                        int hours = curDate.getHours(); 
                        int minutes = curDate.getMinutes(); 
     
                        if (DateFormat.is24HourFormat(Main.this)) { 
                            if (minutes < 10) { 
                                mView.setDigitalText("" + hours + ":0" + minutes); 
                            } else { 
                                mView.setDigitalText("" + hours + ":" + minutes); 
                            } 
                            mClockTypeString = ""; 
                        } else { 
                            hours = hours > 12 ? hours - 12 : hours; 
                            if (minutes < 10) { 
                                mView.setDigitalText("" + hours + ":0" + minutes); 
                            } else { 
                                mView.setDigitalText("" + hours + ":" + minutes); 
                            } 
                        } 
     
                        if (mRunning) 
                            this.sendEmptyMessageDelayed(MSG_UPDATE_TIME, 
                                    UPDATE_INTERNAL);// 每隔一秒就更新一下时间,保持与系统同步,其实如果只需要每分钟更新时间,可以通过接收系统广播同步,这个广播每分钟发送一次。 
                    } 
                } 
            }; 
     
            public DigitalClockUpdater(DigitalTextView view) { 
                mView = view; 
            } 
     
            public void run() { 
                mRunning = true; 
                mUpdateHandler.removeMessages(MSG_UPDATE_TIME); 
                mUpdateHandler.sendEmptyMessage(MSG_UPDATE_TIME); 
            } 
     
            public void stop() { 
                mRunning = false; 
                mView = null; 
                mUpdateHandler.removeMessages(MSG_UPDATE_TIME); 
            } 
        } 
    }<span style="font-size:18px;"> 
    </span> 

  • 相关阅读:
    Android Apk获取包名和Activity名称
    SoupUI接口测试学习分享
    Android 手机自动化测试工具有哪几种?
    SVN和CVS的区别
    名词
    本地解析地址步骤
    python3.6.1+selenium3.0环境安装问题及解决方法
    简述企业信息化与企业架构关系
    企业架构实践的线下公开课学习感悟
    golang 12.9 go mod 实践
  • 原文地址:https://www.cnblogs.com/mochaMM/p/5151109.html
Copyright © 2011-2022 走看看