1. 程式人生 > >自定義控制元件三部曲檢視篇(五)——RecyclerView系列之二ItemDecoration

自定義控制元件三部曲檢視篇(五)——RecyclerView系列之二ItemDecoration

從來不跌倒不算光彩,每次跌倒後能再站起來,才是最大的榮耀。

一、新增分割線

1.1 引入ItemDecoration

在上一篇中,我們講解了RecyclerView的基本使用方法,但有個問題:為什麼Item之間沒有分割線呢?其實,給RecyclerView新增分割線也非常簡單,只需要新增上一句話:

DividerItemDecoration  mDivider = new DividerItemDecoration(this,DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(mDivider);

完整的程式碼如下:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_linear);![在這裡插入圖片描述](https://img-blog.csdn.net/20181007175450753?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hhcnZpYzg4MDkyNQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)

    generateDatas
(); RecyclerView mRecyclerView = (RecyclerView) findViewById(R.id.linear_recycler_view); //線性佈局 LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); mRecyclerView.setLayoutManager(linearLayoutManager)
; //初始化分隔線、新增分隔線 DividerItemDecoration mDivider = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL); mRecyclerView.addItemDecoration(mDivider); RecyclerAdapter adapter = new RecyclerAdapter(this, mDatas); mRecyclerView.setAdapter(adapter); }

這裡實現的效果如下圖所示:
在這裡插入圖片描述
可以看到,這裡只需要新增一句: mRecyclerView.addItemDecoration(mDivider);就可以給底部添加了一條橫線,那什麼是ItemDecoration呢?
首先,我們肯定理解什麼是Item,在這個佈局中,每個Item都單獨佔一行,在沒加ItemDecoration時,下面紅線框中就是一個Item:
在這裡插入圖片描述

1.2 什麼是ItemDecoration

那ItemDecoration與Item是什麼關係呢?對於英語來講,Decoration是裝飾的意思,ItemDecoration就是Item的裝飾。在Item的四周,我們可以給它新增上自定義的裝飾,比如剛才的橫線,就是在底部給它新增一個橫線的裝飾。同樣的,我們也可以在Item的上下左右各新增裝飾,而且這些裝飾是允許我們自定義的。系統只給我們提供了一個現成的Decoration類就是剛才使用的DividerItemDecoration,如果我們想實現其它的裝飾效果,就需要自定義了。下面這些漂亮的效果都可以使用自定義ItemDecoration來實現:
在這裡插入圖片描述
在這裡插入圖片描述在這裡插入圖片描述
在這裡插入圖片描述

2、 自定義ItemDecoration

2.1 getItemOffsets

2.1.1 getItemOffsets的意義

當我們要重寫ItemDecoration時,主要涉及到三個函式:

public class LinearItemDecoration extends RecyclerView.ItemDecoration {
    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);
    }

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDrawOver(c, parent, state);
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
    }
}

這三個函式我們會逐個講解,首先,我們來看看getItemOffsets:
getItemOffsets的主要作用就是給item的四周加上邊距,實現的效果類似於margin,將item的四周撐開一些距離,在撐開這些距離後,我們就可以利用上面的onDraw函式,在這個距離上進行繪圖了。在瞭解了getItemOffsets的作用之後,我們來看看這個函式本身:
getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state)

  • Rect outRect:這個是最難理解的部分,outRect就是表示在item的上下左右所撐開的距離,後面詳細講解。
  • View view:是指當前Item的View物件
  • RecyclerView parent: 是指RecyclerView 本身

下面我們專門來看看Rect outRect這個引數,outRect 中的 top、left、right、bottom四個點,並不是普通意義的座標點,而是指的在Item上、左、右、下各撐開的距離,這個值預設是0,示意圖如下所示:
在這裡插入圖片描述

2.1.2 getItemOffsets示例

我們知道,想要實現分隔線,有一種方法是在Item的上方空出一畫素的間隔,這樣就會漏出底線,看起來就是分割線了。所以我們回到剛才的示例,去掉DividerItemDecoration,改為自定義的LinearItemDecoration。
首先,給整個Activity新增上一個紅色的背景色:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ff0000"
    tools:context=".LinearActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/linear_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </android.support.v7.widget.RecyclerView>

</LinearLayout>

之後,給每個Item新增上預設的背景色白色,這樣有白色的地方就不會透出背景色的紅色了,而沒有白色的地方就會露出紅色:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@android:color/white"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/item_tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:padding="10dp" />

</LinearLayout>

然後就是自定義LinearItemDecoration :

public class LinearItemDecoration extends RecyclerView.ItemDecoration {
    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);
    }

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDrawOver(c, parent, state);
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        outRect.top=1;
    }
}

在這裡,我們將item上方面所撐開的距離硬編碼為1px;

最後,將LinearItemDecoration新增進RecyclerView:

public class LinearActivity extends AppCompatActivity {
    private ArrayList<String> mDatas = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_linear);

        generateDatas();
        RecyclerView mRecyclerView = (RecyclerView) findViewById(R.id.linear_recycler_view);
		…………
        //新增分隔線
        mRecyclerView.addItemDecoration(new LinearItemDecoration());

        RecyclerAdapter adapter = new RecyclerAdapter(this, mDatas);
        mRecyclerView.setAdapter(adapter);
    }
    //其它程式碼,參考原始碼
	…………
}

效果如下圖所示:
在這裡插入圖片描述
可以看到每個Item的上方都出現了一條紅線。尤其從第一個Item可以看出來。
同樣的,如果我們改為底部1px,左側50px,右側100px:

public class LinearItemDecoration extends RecyclerView.ItemDecoration {
	…………
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        outRect.left=50;
        outRect.right=100;
        outRect.bottom=1;
    }
}

看下效果:
在這裡插入圖片描述
從第一個Item可以看出,頂部是沒有紅線的,因為我們沒有設定outRect.top,所以它預設是0,因為outRect.right=100,而outRect.left=50,明顯可以看出右側的紅色寬度是左側的兩倍。

2.2 onDraw

2.2.1 onDraw的用法

在理解了getItemOffsets的用法以後,我們再來看看onDraw函式:

public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
    super.onDraw(c, parent, state);
}

onDraw函式有三個引數,RecyclerView parent, RecyclerView.State state的意義與getItemOffsets的相同。而

  • Canvas c: 是指通過getItemOffsets撐開的空白區域所對應的畫布,通過這個canvas物件,可以在getItemOffsets所撐出來的區域任意繪圖。

那這個就厲害了,我們知道Canvas是有非常豐富的繪圖函式的,那我們先來個簡單的,通過getItemOffsets將Item的左側撐出來150的距離,然後在中間畫一個圓形:

public class LinearItemDecoration extends RecyclerView.ItemDecoration {
    private Paint mPaint;
    public LinearItemDecoration(){
        mPaint = new Paint();
        mPaint.setColor(Color.GREEN);
    }
    @Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
    super.onDraw(c, parent, state);
        int childCount = parent.getChildCount();

        for (int i=0;i<childCount;i++){
            View child = parent.getChildAt(i);
            int cx = 100;
            int cy = child.getTop()+child.getHeight()/2;
            c.drawCircle(cx,cy,20,mPaint);
        }
}

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDrawOver(c, parent, state);
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        outRect.left=200;
        outRect.bottom=1;
    }
}

首先,在getItemOffsets中,將左側撐出200px的距離,同樣底部留出1px的空間以顯示底部分割線。
然後在onDraw中,在每個Item的左側中間畫上半徑為20的綠色圓形。

效果如下圖所示:
在這裡插入圖片描述

需要注意的是,getItemOffsets是針對每個Item都會走一次,也就是說每個Item的outRect都可以不同,但是onDraw和onDrawOver所整個ItemDecoration只執行一次的,並不是針對Item的,所以我們需要在onDraw和onDrawOver中繪圖時,一次性將所有Item的ItemDecoration繪製完成。從上面也可以看出,這裡在onDraw函式中繪圖時,通過for迴圈對每一個item畫上一個綠色圓。

拓展:獲取outRect的各個值
在上面的例子中,我們onDraw中使用到outRect的值時,都是直接使用的數字硬編碼,比如在outRect是我們將左側撐開的距離設定為200,所以畫圓的中心點的X座標就是100,所以在onDraw函式中直接使用了int cx = 100;很明顯,在實際工作中要嚴格避免類似的硬編碼,因為硬編碼會使程式碼變得極其難以維護。那我們怎麼在程式碼中獲取到getItemOffsets中所設定的各個item的outRect的值呢?
可以通過LayoutManager來獲取,方法如下:其中parent是指RecylerView本身,而child是指RecyclerView的Item的View物件

RecyclerView.LayoutManager manager = parent.getLayoutManager();
int left = manager.getLeftDecorationWidth(child);
int top = manager.getTopDecorationHeight(child);
int right = manager.getRightDecorationWidth(child);
int bottom = manager.getBottomDecorationHeight(child);

所以我們上面在onDraw函式中的硬編碼,就可以用下面的動態獲取程式碼來代替:

public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
    super.onDraw(c, parent, state);
        int childCount = parent.getChildCount();
        RecyclerView.LayoutManager manager = parent.getLayoutManager();
        for (int i=0;i<childCount;i++){
            View child = parent.getChildAt(i);
            //動態獲取outRect的left值
            int left = manager.getLeftDecorationWidth(child);
            int cx = left/2;
            int cy = child.getTop()+child.getHeight()/2;
            c.drawCircle(cx,cy,20,mPaint);
        }
}

到這,大家實現開頭講解的這個效果應該不難了:
在這裡插入圖片描述
該工程原始碼地址:https://github.com/vipulasri/Timeline-View ,他是通過自定義View來實現的,大家也可以嘗試通過RecyclerView的ItemDecoration來實現出來。

原始碼在文章底部給出

2.2.2 onDraw的問題

如果我們在將上面畫圓的例子修改下,將畫圓改為繪製一個圖片:
在這裡插入圖片描述
程式碼如下:

public class LinearItemDecoration extends RecyclerView.ItemDecoration {
    private Paint mPaint;
    private Bitmap mBmp;

    public LinearItemDecoration(Context context) {
        mPaint = new Paint();
        mPaint.setColor(Color.GREEN);
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 2;
        mBmp = BitmapFactory.decodeResource(context.getResources(),R.mipmap.icon,options);
    }

    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);
        int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = parent.getChildAt(i);
            c.drawBitmap(mBmp,0,child.getTop(), mPaint);
        }
    }

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDrawOver(c, parent, state);
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        outRect.left = 200;
        outRect.bottom = 1;
    }
}

首先,因為圖片比較大,在LinearItemDecoration初始化的時候,通過options.inSampleSize引數將圖片縮放小為原大小的1/2;

public LinearItemDecoration(Context context) {
	…………
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = 2;
    mBmp = BitmapFactory.decodeResource(context.getResources(),R.mipmap.icon,options);
}

同樣,在getItemOffsets中,將左側邊距設定為200,底部預留一畫素顯示分割線。
最後,在onDraw中,將圖形在每個Item的左上角顯示出來。
效果如下圖所示:
在這裡插入圖片描述
如果我們把bitmap縮放去掉:

    public LinearItemDecoration(Context context) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        //options.inSampleSize = 2;
        mBmp = BitmapFactory.decodeResource(context.getResources(),R.mipmap.icon,options);
    }

效果圖如下:
在這裡插入圖片描述
可以看到當圖片過大時,在超出getItemOffsets函式所設定的outRect範圍的部分將是不可見的。這是因為在整個繪製流程中,是選呼叫ItemDecoration的onDraw函式,然後再呼叫Item的onDraw函式,最後呼叫ItemDecoration的onDrawOver函式。
所以在ItemDecoration的onDraw函式中繪製的內容,當超出邊界時,會被Item所覆蓋。但是因為最後才呼叫ItemDecoration的OnDrawOver函式,所以在onDrawOver中繪製的內容就不受outRect邊界的限制,可以覆蓋Item的區域顯示。

原始碼在文章底部給出

2.3 onDrawOver

上面我們已經提到,ItemDecoration與Item的繪製順序為:decoration 的 onDraw->item的 onDraw->decoration 的 onDrawOver,這三者是依次發生的。
所以,onDrawOver 是繪製在最上層的,所以它的繪製位置並不受限制(當然,decoration 的 onDraw 繪製範圍也不受限制,只不過不可見,被item所覆蓋),所以利用 onDrawOver 可以做很多事情,例如為 RecyclerView 整體頂部繪製一個蒙層、超出itemDecoration的範圍繪製圖像。
比如,我們實現下面這樣的效果:
在這裡插入圖片描述
在這個效果中,我們在最頂部繪製了一個漸變蒙版,而且每隔五個item繪製一個勳章。動圖效果是這樣的:
在這裡插入圖片描述
可見這個蒙層是一直顯示在頂部的。下面我們就來看看具體 實現吧。
1、新增圖片
第一步,當然是將勳章圖片(xunzhang.png)加入res/mipmap資料夾中或者res/drawable資料夾中。
在這裡插入圖片描述
2、初始化
然後在LinearItemDecoration初始化時,將圖片轉為bitmap物件:

public class LinearItemDecoration extends RecyclerView.ItemDecoration {
    private Paint mPaint;
    private Bitmap mMedalBmp;

    public LinearItemDecoration(Context context) {
        mPaint = new Paint();
        mPaint.setColor(Color.GREEN);
        BitmapFactory.Options options = new BitmapFactory.Options();
        mMedalBmp = BitmapFactory.decodeResource(context.getResources(), R.mipmap.xunzhang);
    }
}

3、繪製勳章
在onDrawOver中將勳章每隔五個item繪製出來

public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
    super.onDrawOver(c, parent, state);
    //畫勳章
    RecyclerView.LayoutManager manager = parent.getLayoutManager();
    int childCount = parent.getChildCount
            
           

相關推薦

定義控制元件三部曲檢視——RecyclerView系列ItemDecoration

從來不跌倒不算光彩,每次跌倒後能再站起來,才是最大的榮耀。 一、新增分割線 1.1 引入ItemDecoration 在上一篇中,我們講解了RecyclerView的基本使用方法,但有個問題:為什麼Item之間沒有分割線呢?其實,給RecyclerView新

定義控制元件三部曲檢視——RecyclerView系列之一簡單使用

絕望的時候不要那麼絕望,高興的時候不要那麼高興,是你慢慢會學會的。 ——董卿 轉了一年多,又回來繼續做Android。果然還是看到程式碼最讓我興奮……但有些事,沒經歷過,總歸還是遺憾的。在VIVO的遊戲中心,有一個特別炫酷的功能: 這個功能就是使

定義控制元件三部曲檢視——瀑布流容器WaterFallLayout實現

前言:只要在前行,夢想就不再遙遠 系列文章: 前面兩節講解了有關ViewGroup的onMeasure、onLayout的知識,這節我們深入性地探討一下,如何實現經常見到的瀑布流容器,本節將實現的效果圖如下: 從效果圖中可以看出這裡要完成的

C#定義控制元件程式設計輕鬆入門1

前 言 話說,許多新手在接觸C#的時候都覺得C#使用起來特別容易方便,相對C++來說沒有那麼多的繁瑣,比如C++每次在使用一個函式,都要先在標頭檔案中宣告一遍,而C#宣告和實現都在一起,立馬可以用。而且不會一會要寫指標一會兒要寫引用,如果是遇到VC那些控制代碼就把頭給搞大。 隨著

四十九c#Winform定義控制元件-下拉框表格

前提 入行已經7,8年了,一直想做一套漂亮點的自定義控制元件,於是就有了本系列文章。 GitHub:https://github.com/kwwwvagaa/NetWinformControl 碼雲:https://gitee.com/kwwwvagaa/net_winform_custom_contr

定義控制元件三部曲繪圖——Path貝賽爾曲線和手勢軌跡、水波紋效果

前言:好想義無反顧地追逐夢想從這篇開始,我將延續androidGraphics系列文章把圖片相關的知識給大家講完,這一篇先稍微進階一下,給大家把《android Graphics(二):路徑及文字》略去的quadTo(二階貝塞爾)函式,給大家補充一下。 本篇最終將以兩個例子給

定義控制元件三部曲動畫——alpha、scale、translate、rotate、set的xml屬性及用法

前言:這幾天做客戶回訪,感觸很大,使用者只要是留反饋資訊,總是一種恨鐵不成鋼的心態,想用你的app,卻是因為你的技術問題,讓他們不得不放棄,而你一個回訪電話卻讓他們盡釋前嫌,當最後把手機號留給他們以便隨時溝通的時候,總會發來一條條的鼓勵簡訊,讓我不自主的開始內疚。哎,多麼可愛

定義控制元件三部曲繪圖十三——Canvas與圖層(一)

前言:猛然知道姥姥79了,我好怕,好想哭系列文章:一、如何獲得一個Canvas物件方法一:自定義view時, 重寫onDraw、dispatchDraw方法(1)、定義 我們先來看一下onDraw、dispatchDraw方法的定義protected void onDraw(

定義控制元件三部曲動畫——Interpolator插值器

前言:雖然我不太能欣賞的了帕爾哈提的音樂,但我確實很欣賞他的人生態度,專心做自己,不想名利得失,有一天,你想要的東西都會來。其實我覺得,人生最可怕的就是停止不前,只要一直前行,總有一天會到達人生巔峰。相關文章:一、概述Interpolator屬性是Animation類的一個X

定義控制元件三部曲動畫(十一)——layoutAnimation與gridLayoutAnimation

前言:人或許天生是懶惰的,明知道的不足,卻不努力彌補。 前幾篇給大家講述瞭如何針對某一個控制元件應用動畫,這篇將給大家講解如何給容器中的控制元件應用統一動畫。即在容器中控制元件出現時,不必為每個控制元件新增進入動畫,可以在容器中為其新增統一的進入和

定義控制元件三部曲繪圖(十)——RadialGradient與水波紋按鈕效果

前言:每當感嘆自己的失敗時,那我就問你,如果讓你重新來一次,你會不會成功?如果會,那說明並沒有拼盡全力。 系列文章: 最近博主實在是太忙了,部落格更新實在是太慢了,真是有愧大家。 這篇將是Shader的最後一篇,下部分,我們將講述Canvas變

定義控制元件三部曲動畫(十)——聯合動畫的XML實現與使用示例

前言:不畏人生,或許才能方得始終;大膽拼,大膽闖是要有一定資本的,在能力不到的時候,就只有選擇忍氣吞聲! 上篇給大家講了有關AnimatorSet的程式碼實現方法,這篇我們就分別來看看如何利用xml來實現ValueAnimator、ObjectAn

定義控制元件 輪盤 來源於GITHUB記錄,筆記

自定義控制元件:輪盤抽獎 -------邏輯程式碼(輪盤的類)首先要寫一個類繼承SurfaceView 實現Callback和Runnable方法: //所使用的包 import android.content.Context; import android.graphics.Ca

定義控制元件 輪盤 來源於GITHUB記錄,筆記

自定義控制元件:輪盤抽獎 -------邏輯程式碼(輪盤的類)首先要寫一個類繼承SurfaceView 實現Callback和Runnable方法: //所使用的包 import android.content.Context; import android.

Android定義控制元件--圓形進度條中間有圖diao

智慧家居越來越流行,在智慧家居中我們常要表現一些資料的百分比 圓形度條中間加個圖是一種非常流行的自定義View 1.第一步 你首先需要對類進行繼承View public class CircleProgressImageView extends View 2.第二步 要實

Qt編寫定義控制元件37-發光按鈕會呼吸的痛

一、前言 這個控制元件是好早以前寫的,已經授權過好幾個人開源過此控制元件程式碼,比如紅磨坊小胖,此控制元件並不是來源於真實需求,而

[C#] 原創一步一步教你定義控制元件——02,ScrollBar滾動條

一、前言 技術沒有先進與落後,只有合適與不合適。 本篇的自定義控制元件是:滾動條(ScollBar)。 我們可以在網上看到很多自定義的滾動條控制元件,它們大都是使用UserControl去做,即至少使用一個Panel或其它控制元件作滑塊,使用UserControl本身或另一個控制元件作為背景條,而有的複雜的還

[C#] 原創一步一步教你定義控制元件——03,SwitchButton開關按鈕

一、前言 技術沒有先進與落後,只有合適與不合適。 本篇的自定義控制元件是:開關按鈕(SwitchButton)。 開關按鈕非常簡單,實現方式也多種多樣,比如常見的:使用兩張不同的按鈕圖片,代表開和關,然後在點選時切換這兩張圖片。 而本篇和前兩篇一脈相承,都是繼承Control,使用GDI+去實現。因為都是相同

[C#] 原創一步一步教你定義控制元件——04,ProgressBar進度條

一、前言 技術沒有先進與落後,只有合適與不合適。 本篇的自定義控制元件是:進度條(ProgressBar)。 進度條的實現方式多種多樣,主流的方式有:使用多張圖片去實現、使用1個或2個Panel放到UserControl上去實現、過載系統進度條去實現等等。 本次所實現的進度條仍是使用GDI+去實現。當然,如果

[C#] 原創一步一步教你定義控制元件——05,Label原生控制元件

一、前言 技術沒有先進與落後,只有合適與不合適。 自定義控制元件可以分為三類: 一類是“無中生有”。就如之前文章中的的那些控制元件,都是繼承基類Control,來實現特定的功能效果; 一類是“有則改之”。是對原生控制元件的改造,以達到特定的功能效果; 一類是“使用者控制元件”。是將多個控制元件進行組合,以實現