01.public class TextProgressBar extends RelativeLayout implements OnChronometerTickListener {  
02.    public static final String TAG = \"TextProgressBar\";  
03.     
04.    static final int CHRONOMETER_ID = android.R.id.text1;  
05.    static final int PROGRESSBAR_ID = android.R.id.progress;  
06.     
07.    Chronometer mChronometer = null;  
08.    ProgressBar mProgressBar = null;  
09.     
10.    long mDurationBase = -1;  
11.    int mDuration = -1;  
12.    boolean mChronometerFollow = false;  
13.    int mChronometerGravity = Gravity.NO_GRAVITY;  
14.     
15.    public TextProgressBar(Context context, AttributeSet attrs, int defStyle) {  
16.        super(context, attrs, defStyle);  
17.    }  
18.    public TextProgressBar(Context context, AttributeSet attrs) {  
19.        super(context, attrs);  
20.    }  
21.    public TextProgressBar(Context context) {  
22.        super(context);  
23.    }  
24.    //Android开发网提示关键部分在这里  
25. 
26.    @Override 
27.    public void addView(View child, int index, ViewGroup.LayoutParams params) {  
28.        super.addView(child, index, params);  
29.         
30.        int childId = child.getId();  
31.        if (childId == CHRONOMETER_ID && child instanceof Chronometer) {  
32.            mChronometer = (Chronometer) child;  
33.            mChronometer.setOnChronometerTickListener(this);  
34.             
35.            // Check if Chronometer should move with with ProgressBar  
36.            mChronometerFollow = (params.width == ViewGroup.LayoutParams.WRAP_CONTENT);  
37.            mChronometerGravity = (mChronometer.getGravity() & Gravity.HORIZONTAL_GRAVITY_MASK);  
38.             
39.        } else if (childId == PROGRESSBAR_ID && child instanceof ProgressBar) {  
40.            mProgressBar = (ProgressBar) child;  
41.        }  
42.    }  
43.   
44.    @android.view.RemotableViewMethod  
45.    public void setDurationBase(long durationBase) {  
46.        mDurationBase = durationBase;  
47.         
48.        if (mProgressBar == null || mChronometer == null) {  
49.            throw new RuntimeException(\"Expecting child ProgressBar with id \" +  
50.                    \"\'android.R.id.progress\' and Chronometer id \'android.R.id.text1\'\");  
51.        }  
52.         
53.        // Update the ProgressBar maximum relative to Chronometer base  
54.        mDuration = (int) (durationBase - mChronometer.getBase());  
55.        if (mDuration <= 0) {  
56.            mDuration = 1;  
57.        }  
58.        mProgressBar.setMax(mDuration);  
59.    }  
60.      
61.   
62.    public void onChronometerTick(Chronometer chronometer) {  
63.        if (mProgressBar == null) {  
64.            throw new RuntimeException(  
65.                \"Expecting child ProgressBar with id \'android.R.id.progress\'\");  
66.        }  
67.         
68.        // Stop Chronometer if we\'re past duration  
69.        long now = SystemClock.elapsedRealtime();  
70.        if (now >= mDurationBase) {  
71.            mChronometer.stop();  
72.        }  
73.   
74.        int remaining = (int) (mDurationBase - now);  
75.        mProgressBar.setProgress(mDuration - remaining);  
76.          
77.    
78.        if (mChronometerFollow) {  
79.            RelativeLayout.LayoutParams params;  
80.              
81.   
82.            params = (RelativeLayout.LayoutParams) mProgressBar.getLayoutParams();  
83.            int contentWidth = mProgressBar.getWidth() - (params.leftMargin + params.rightMargin);  
84.            int leadingEdge = ((contentWidth * mProgressBar.getProgress()) /  
85.                    mProgressBar.getMax()) + params.leftMargin;  
86.              
87.   
88.            int adjustLeft = 0;  
89.            int textWidth = mChronometer.getWidth();  
90.            if (mChronometerGravity == Gravity.RIGHT) {  
91.                adjustLeft = -textWidth;  
92.            } else if (mChronometerGravity == Gravity.CENTER_HORIZONTAL) {  
93.                adjustLeft = -(textWidth / 2);  
94.            }  
95.              
96.   
97.            leadingEdge += adjustLeft;  
98.            int rightLimit = contentWidth - params.rightMargin - textWidth;  
99.            if (leadingEdge < params.leftMargin) {  
100.                leadingEdge = params.leftMargin;  
101.            } else if (leadingEdge > rightLimit) {  
102.                leadingEdge = rightLimit;  
103.            }  
104.             
105.            params = (RelativeLayout.LayoutParams) mChronometer.getLayoutParams();  
106.            params.leftMargin = leadingEdge;  
107.              
108.   
109.            mChronometer.requestLayout();  
110.             
111.        }  
112.    }  
113.}