1、 自定義的單個控件
分別是重新繼承View或者其子類和SurfaceView或者其子類。如果是一般的應用程序開始,繼承View或者其子類就可以了,我們需要做的,就是重寫onDraw(canver)。SuerfaceVIEw主要用於幀數要求比較高的應用,如“視頻播放”和游戲開發,尤其是3D游戲開發,這裡不詳細敘述,以後說到關於游戲開發,我會專以一個帖子講解的。
2、 自定義的組合控件
組合的控件,因名思議,就是把幾個控件組合在一起,組合成一個更大的控件。一般是繼承一個Layout,如ReleativeLayout、LinearLayout、TableLayout等等,視具體情況而定。當然,裝在Layout裡而子控件,可以是系統自帶的,也可以通過第一方式自定義的控件。
這樣,只要大家發揮想象,通過上面兩種方法,就可以組合出千變萬化的控件了,一句話“沒有做不到,只有想不到”。
一、原理說完 ,下面先上圖,讓大家看看最終效果吧,如下圖:
二、要求:
要求進度條能從左到右減少。系統自帶的進度條,好像沒有方向可以設置的
三、技術點和難點
主要的技術點:android的Handle機制,ReleativeLayout的相對布局。
主要的難點:在android上,是不可以動態修改view的layout_width和layout_height的,因此要動態修改進度條的長度,需要不斷“刪除—增加”ImageView的方式來實現,而每次add進parent的ImageView的layout_width需要根據當前parent的width、max_value、current_progress三者計算出來,長度 = parent_width * (current_progress/max_value);另外還有一點,非常重要的,就是每次更換ImageVIEw時,都必須交生成一個線程,post給handle來做,這裡才不會造成界面阻塞,這一點很重要,不然界面要卡死的!!
Java代碼:
- public class MobileTokenProcessBar extends RelativeLayout {
- private int m_max = 20;
- private int m_process = 0;
- private ImageView mImageVIEw = null;
- private LayoutParams params;
- private Handler mHandler;
- private Thread mThread = new Thread(new Runnable() {
- @Override
- public void run() {
- reFlashPorcess(m_process);//界面的修改,交由線程來處理
- }
- });
- public MobileTokenProcessBar(Context context, AttributeSet attrs) {
- super(context, attrs);
- init();
- }
- public MobileTokenProcessBar(Context context){
- super(context);
- init();
- }
- private void init(){
- setBackgroundResource(R.drawable.processbar_out_bg);
- mHandler = new Handler(getContext().getMainLooper());
- params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
- params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
- }
- public void setMax(int max){
- m_max = max;
- }
- public int getMax(){
- return m_max;
- }
- public void setProgress(int process){
- if(process <= m_max ){
- m_process = process;
- mHandler.post(mThread);
- }
- }
- public int getProgress(){
- return m_process;
- }
- private int getCountLength(){
- return (getWidth() - 16) * m_process / m_max;
- }
- private void reFlashPorcess(int process){
- if(mImageVIEw != null)
- removeView(mImageVIEw);
- mImageVIEw = null;
- mImageView = new ImageVIEw(getContext());
- mImageView.setAdjustVIEwBounds(true);
- mImageVIEw.setScaleType(ScaleType.FIT_XY);
- mImageVIEw.setImageResource(R.drawable.processbar_in_bg);
- params.width = getCountLength();
- addView(mImageVIEw, params);
- }
- }