編輯:關於Android編程
public int save() public int save(int saveFlags) public int saveLayer(RectF bounds, Paint paint, int saveFlags) public int saveLayer(float left, float top, float right, float bottom,Paint paint, int saveFlags) public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) public int saveLayerAlpha(float left, float top, float right, float bottom,int alpha, int saveFlags)這段我們先關注前四個,save的兩個函數和saveLayer的兩個函數;我們知道他們兩個不同之處在於saveLayer會新建一個畫布,而save函數則不會新建畫布;它們都具有Flag標識,這些Flag標識的意義和使用范圍如下:
public class MATRIX_SAVE_FLAG_View extends View { private Paint mPaint; public MATRIX_SAVE_FLAG_View(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(LAYER_TYPE_SOFTWARE,null); mPaint = new Paint(); mPaint.setColor(Color.GREEN); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.save(Canvas.MATRIX_SAVE_FLAG); canvas.rotate(40); canvas.drawRect(100,0,200,100,mPaint); canvas.restore(); mPaint.setColor(Color.YELLOW); canvas.drawRect(100,0,200,100,mPaint); } }我們直接看OnDraw函數,先調用 canvas.save(Canvas.MATRIX_SAVE_FLAG)將canvas的位置矩陣保存起來,然後將畫布旋轉40度之後,畫一個綠色矩形;
很明顯,在canvas.restore()後,畫布的旋轉給恢復到了原來了狀態。
然後我們再來看看,如果我們給畫布裁剪,看還能不能被恢復
public class MATRIX_SAVE_FLAG_View extends View { private Paint mPaint; public MATRIX_SAVE_FLAG_View(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(LAYER_TYPE_SOFTWARE,null); mPaint = new Paint(); mPaint.setColor(Color.GREEN); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.save(Canvas.MATRIX_SAVE_FLAG); canvas.clipRect(100,0,200,100); canvas.drawColor(Color.GREEN); canvas.restore(); canvas.drawColor(Color.YELLOW); } }效果圖如下:
從效果圖來看,我們恢復畫布後,把畫布全部染成了黃色,但並沒有染全屏幕的畫布,而只是clip後的一部分,這說明,被裁剪的畫布沒有被還原!
前面我們說了調用 canvas.save(Canvas.MATRIX_SAVE_FLAG)只會保存了位置矩陣!恢復時,也只會恢復畫布的位置信息,有關畫布的大小,是不會被恢復的!
public class MATRIX_SAVE_FLAG_View extends View { private Paint mPaint; public MATRIX_SAVE_FLAG_View(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(LAYER_TYPE_SOFTWARE,null); mPaint = new Paint(); mPaint.setColor(Color.GREEN); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.RED); canvas.saveLayer(0,0,getWidth(),getHeight(),mPaint,Canvas.MATRIX_SAVE_FLAG|Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); canvas.rotate(40); canvas.drawRect(100,0,200,100,mPaint); canvas.restore(); mPaint.setColor(Color.YELLOW); canvas.drawRect(100,0,200,100,mPaint); } }效果圖如下:
這裡在保存Flag時,多了一個Canvas.HAS_ALPHA_LAYER_SAVE_FLAG,表示在新建的畫布在合成到上一個畫布上時,直接覆蓋,不清空所在區域原圖像,這個標識這裡先忽略,我們後面會具體講。
效果與原因都是與save()相同,指定保存Canvas.MATRIX_SAVE_FLAG,即canvas的位置信息,當調用canvas.revert()後,原始畫布的旋轉被恢復。所以再次畫圖到原始畫布上時,是沒有旋轉的。
我們還是直接來看例子吧,裁剪:
下面我們舉個例子來看看
public class MATRIX_SAVE_FLAG_View extends View { private Paint mPaint; public MATRIX_SAVE_FLAG_View(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(LAYER_TYPE_SOFTWARE,null); mPaint = new Paint(); mPaint.setColor(Color.GREEN); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.GREEN); canvas.saveLayer(0,0,getWidth(),getHeight(),mPaint,Canvas.MATRIX_SAVE_FLAG|Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); canvas.clipRect(100,0,200,100); canvas.restore(); canvas.drawColor(Color.YELLOW); } }效果圖如下:
與上面的例子一樣,在saveLayer中也只是保存Canvas.MATRIX_SAVE_FLAG,即canvas的位置信息,之後調用canvas.clipRect(100,0,200,100);將畫板裁剪,注意我們在講解canvas時提到了,無論哪個圖層調用canvas的位置變換和裁剪操作,所有的畫布都會受到連累,這些連累也只表現在畫布以後的繪圖上,之前畫過的圖像不會受到影響。
所以在clipRect之前畫出來的全屏綠色是不受影響的,當restore()以後,canvas只恢復了原始畫布的位置信息而原始畫布的大小卻無法被恢復,所以當再調用 canvas.drawColor(Color.YELLOW),也只能畫出來一小塊了
注意:在上面的例子中用到了canvas.clipRect(),這個函數是不支持硬件加速的,原因參見《自定義控件三部曲之繪圖篇(十)——Paint之setXfermode(一)》,所以需要添加setLayerType函數來禁用硬件加速。
所以MATRIX_SAVE_FLAG標識的結論來了:
1、當save\saveLayer調用Canvas.MATRIX_SAVE_FLAG標識時只會保存畫布的位置矩陣信息,在canvas.restore()時也只會恢復位置信息,而改變過的畫布大小是不會被恢復的。
2、當使用canvas.saveLayer(Canvas.MATRIX_SAVE_FLAG)時,需要與Canvas.HAS_ALPHA_LAYER_SAVE_FLAG一起使用,不然新建畫布所在區域原來的圖像將被清空。(後面會講原因)
public class CLIP_SAVE_FLAG_View extends View { private Paint mPaint; public CLIP_SAVE_FLAG_View(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(LAYER_TYPE_SOFTWARE,null); mPaint = new Paint(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.RED); canvas.save(Canvas.CLIP_SAVE_FLAG); canvas.clipRect(100,0,200,100); canvas.restore(); canvas.drawColor(Color.YELLOW); } }效果圖如下:
從效果圖中可以看出在canvas.restore()後,canvas被恢復到初始化的全屏大小。
然後我們再看一個旋轉的例子
public class CLIP_SAVE_FLAG_View extends View { private Paint mPaint; public CLIP_SAVE_FLAG_View(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(LAYER_TYPE_SOFTWARE,null); mPaint = new Paint(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setColor(Color.GREEN); canvas.drawRect(100,0,200,100,mPaint); canvas.save(Canvas.CLIP_SAVE_FLAG); canvas.rotate(40); canvas.restore(); mPaint.setColor(Color.YELLOW); canvas.drawRect(100,0,200,100,mPaint); } }效果圖如下:
我們先畫了一個綠色的矩形,之後旋轉畫布,然後在調用 canvas.restore()恢復畫布之後,再畫上一個同樣的黃色矩形。
從效果圖中可以看出,canvas在恢復時,並沒有恢復旋轉的畫布,這也就是Canvas.CLIP_SAVE_FLAG的意義所在,只保存裁剪信息,不保存位置信息,所以恢復時,位置信息是不會被恢復的!
public class CLIP_SAVE_FLAG_View extends View { private Paint mPaint; public CLIP_SAVE_FLAG_View(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(LAYER_TYPE_SOFTWARE,null); mPaint = new Paint(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.saveLayer(0,0,getWidth(),getHeight(),mPaint,Canvas.CLIP_SAVE_FLAG|Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); canvas.clipRect(100,0,200,100); canvas.restore(); canvas.drawColor(Color.YELLOW); } }效果圖如下:
效果與canvas.save一樣,原因也很簡單,因為Canvas.CLIP_SAVE_FLAG標識是可以恢復裁剪信息的。
然後再來看看旋轉。
public class CLIP_SAVE_FLAG_View extends View { private Paint mPaint; public CLIP_SAVE_FLAG_View(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(LAYER_TYPE_SOFTWARE,null); mPaint = new Paint(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint.setColor(Color.GREEN); canvas.drawRect(100,0,200,100,mPaint); canvas.saveLayer(0,0,getWidth(),getHeight(),mPaint,Canvas.CLIP_SAVE_FLAG|Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); canvas.rotate(40); canvas.restore(); mPaint.setColor(Color.YELLOW); canvas.drawRect(100,0,200,100,mPaint); } }效果與canvas.save相同
因為Canvas.CLIP_SAVE_FLAG不能保存位置信息,所以在canvas.restore()後,旋轉並沒有被恢復。
所以CLIP_SAVE_FLAG標識的結論來了:
1、當save/saveLayer調用 Canvas.CLIP_SAVE_FLAG時只會保存畫布的裁剪信息,在canvas.restore()時也只會恢復裁剪信息,而改變過的畫布位置信息是不會被恢復的。
2、當使用canvas.saveLayer(Canvas.CLIP_SAVE_FLAG)時,需要與Canvas.HAS_ALPHA_LAYER_SAVE_FLAG一起使用,不然新建畫布所在區域原來的圖像將被清空。
public class ALPHA_COLOR_FALG_VIEW extends View { private Paint mPaint; public ALPHA_COLOR_FALG_VIEW(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(View.LAYER_TYPE_SOFTWARE, null); mPaint = new Paint(); mPaint.setColor(Color.GREEN); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.RED); canvas.saveLayer(0,0,500,500,mPaint,Canvas.FULL_COLOR_LAYER_SAVE_FLAG); canvas.drawRect(100,100,300,300,mPaint); canvas.restore(); } }效果圖如下:
我們在saveLayer時,新建bitmap畫布的大小為(0,0,500,500),然後在新建畫布中畫了一個矩形(100,100,300,300),由於我們使用的標識是Canvas.FULL_COLOR_LAYER_SAVE_FLAG,所以新建畫布在與上一層畫布合成時,會先把上一層畫布對應區域的圖像清空掉,然後再蓋上新建畫布。由於新建畫布中除了綠色矩形,其它位置都是透明像素,所以就顯示出Activity的底色(黑色)。如果你把activity的背景色在xml中設置為白色,做出來的效果圖中,露出來的就是白色了:
main.xml
對應的效果為:…………
public class ALPHA_COLOR_FALG_VIEW extends View { private Paint mPaint; public ALPHA_COLOR_FALG_VIEW(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(View.LAYER_TYPE_SOFTWARE, null); mPaint = new Paint(); mPaint.setColor(Color.GREEN); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.RED); canvas.saveLayer(0,0,500,500,mPaint,Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); canvas.drawRect(100,100,300,300,mPaint); canvas.restore(); } }效果圖為:
從效果圖中可以看出,saveLayer新建的畫布在與上一層畫布合成時,並沒有把上一層畫布對應區域清空,而是直接蓋在上面。
public class ALPHA_COLOR_FALG_VIEW extends View { private Paint mPaint; public ALPHA_COLOR_FALG_VIEW(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(View.LAYER_TYPE_SOFTWARE, null); mPaint = new Paint(); mPaint.setColor(Color.GREEN); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.RED); canvas.saveLayer(0,0,500,500,mPaint,Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.FULL_COLOR_LAYER_SAVE_FLAG); canvas.drawRect(100,100,300,300,mPaint); canvas.restore(); } }還是上面的例子,我們同時加入兩個標識,看以哪個結果顯示,效果圖如下:
所以從效果圖中也可以看出,當這兩個標識同時使用時,以Canvas.HAS_ALPHA_LAYER_SAVE_FLAG為主;
public class ALPHA_COLOR_FALG_VIEW extends View { private Paint mPaint; public ALPHA_COLOR_FALG_VIEW(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(View.LAYER_TYPE_SOFTWARE, null); mPaint = new Paint(); mPaint.setColor(Color.GREEN); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.RED); canvas.saveLayer(0,0,500,500,mPaint,Canvas.MATRIX_SAVE_FLAG); canvas.rotate(40); canvas.drawRect(100, 100, 300, 300, mPaint); canvas.restore(); } }效果圖如下:
從效果圖中可以看出,在默認情況下使用的是Canvas.FULL_COLOR_LAYER_SAVE_FLAG標識,即先清空上一層畫布對應區域的圖像,然後再合成,所以這也是我們在上面的例子中強制添加HAS_ALPHA_LAYER_SAVE_FLAG標識的原因
所以有關這兩個標識的結論來了:
1、HAS_ALPHA_LAYER_SAVE_FLAG表示新建的bitmap畫布在與上一個畫布合成時,不會將上一層畫布內容清空,直接蓋在上一個畫布內容上面。
2、FULL_COLOR_LAYER_SAVE_FLAG則表示新建的bimap畫布在與上一個畫布合成時,先將上一層畫布對應區域清空,然後再蓋在上面。
3、當HAS_ALPHA_LAYER_SAVE_FLAG與FULL_COLOR_LAYER_SAVE_FLAG兩個標識同時指定時,以HAS_ALPHA_LAYER_SAVE_FLAG為主
4、當即沒有指定HAS_ALPHA_LAYER_SAVE_FLAG也沒有指定FULL_COLOR_LAYER_SAVE_FLAG時,系統默認使用FULL_COLOR_LAYER_SAVE_FLAG;
public class CLIP_TO_LAYER_SAVE_FLAG_VIEW extends View { private Paint mPaint; public CLIP_TO_LAYER_SAVE_FLAG_VIEW(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(View.LAYER_TYPE_SOFTWARE, null); mPaint = new Paint(); mPaint.setColor(Color.GREEN); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.RED); canvas.saveLayer(0, 0, 500, 500, mPaint, Canvas.CLIP_TO_LAYER_SAVE_FLAG); canvas.restore(); canvas.drawColor(Color.YELLOW); } }效果圖如下:
從效果圖中可以看出,當我們調用canvas.saveLayer(0, 0, 500, 500, mPaint, Canvas.CLIP_TO_LAYER_SAVE_FLAG)時,canvas畫板就被裁剪了,不僅影響了自己,而且還把view的原始畫布給影響了,雖然在調用了canvas.restore(),但最後一句在將原始畫布填充為黃色,也可以看出,原始畫布沒有被恢復!
public class CLIP_TO_LAYER_SAVE_FLAG_VIEW extends View { private Paint mPaint; public CLIP_TO_LAYER_SAVE_FLAG_VIEW(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(View.LAYER_TYPE_SOFTWARE, null); mPaint = new Paint(); mPaint.setColor(Color.GREEN); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.RED); canvas.saveLayer(0, 0, 500, 500, mPaint, Canvas.CLIP_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG); canvas.restore(); canvas.drawColor(Color.YELLOW); } }效果圖如下:
從效果圖中可以看出canvas被恢復了,不過canvas被恢復也,也就失去了Canvas.CLIP_TO_LAYER_SAVE_FLAG標識的意義了。
所以這個CLIP_TO_LAYER_SAVE_FLAG標識的結論來了:
1、CLIP_TO_LAYER_SAVE_FLAG意義是在新建bitmap前,先把canvas給裁剪,一旦畫板被裁剪,那麼其中的各個畫布都會被受到影響。而且由於它是在新建bitmap前做的裁剪,所以是無法恢復的;
2、當CLIP_TO_LAYER_SAVE_FLAG與CLIP_SAVE_FLAG標識共用時,在調用restore()後,畫布將被恢復
public int save() public int save(int saveFlags) public int saveLayer(RectF bounds, Paint paint, int saveFlags) public int saveLayer(float left, float top, float right, float bottom,Paint paint, int saveFlags) public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) public int saveLayerAlpha(float left, float top, float right, float bottom,int alpha, int saveFlags)在save()、saveLayer()、saveLayerAlpha()保存畫布後,都會返回一個ID值,這個ID值表示當前保存的畫布信息的棧層索引(從0開始),比如保存在第三層,則返回2;
public void restoreToCount(int saveCount);它表示一直退棧,一直退到指定count的層數為棧頂為止;注意這個saveCount起始值是從1開始的,也就是說它比對應棧的索引要多1;
int id = canvas.saveLayer(0,0,getWidth(),getHeight(),mPaint,Canvas.ALL_SAVE_FLAG); canvas.restoreToCount(id);調用canvas.saveLayer後,新保存的畫布放在了第三層,返回的id的值是對應的索引即2
public class RestoreToCountView extends View { private Paint mPaint; private String TAG = "qijian"; public RestoreToCountView(Context context, AttributeSet attrs) { super(context, attrs); mPaint = new Paint(); mPaint.setColor(Color.RED); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int id1 = canvas.save(); canvas.clipRect(0,0,800,800); canvas.drawColor(Color.RED); Log.d(TAG,"count:"+canvas.getSaveCount()+" id1:"+id1); int id2 = canvas.saveLayer(0,0,getWidth(),getHeight(),mPaint,Canvas.ALL_SAVE_FLAG); canvas.clipRect(100,100,700,700); canvas.drawColor(Color.GREEN); Log.d(TAG,"count:"+canvas.getSaveCount()+" id2:"+id2); int id3 = canvas.saveLayerAlpha(0,0,getWidth(),getHeight(),0xf0,Canvas.ALL_SAVE_FLAG); canvas.clipRect(200,200,600,600); canvas.drawColor(Color.YELLOW); Log.d(TAG,"count:"+canvas.getSaveCount()+" id3:"+id3); int id4 = canvas.save(Canvas.ALL_SAVE_FLAG); canvas.clipRect(300,300,500,500); canvas.drawColor(Color.BLUE); Log.d(TAG,"count:"+canvas.getSaveCount()+" id4:"+id4); } }在onDraw函數中,我們連續對canvas做裁剪,並且在裁剪後,把當前畫布畫上一層不同的顏色,然後把當前的棧的層數和最高層的索引打出來
Log日志如下:
然後我們更改一下上面的代碼:
protected void onDraw(Canvas canvas) { super.onDraw(canvas); int id1 = canvas.save(); canvas.clipRect(0,0,800,800); canvas.drawColor(Color.RED); Log.d(TAG,"count:"+canvas.getSaveCount()+" id1:"+id1); int id2 = canvas.saveLayer(0,0,getWidth(),getHeight(),mPaint,Canvas.ALL_SAVE_FLAG); canvas.clipRect(100,100,700,700); canvas.drawColor(Color.GREEN); Log.d(TAG,"count:"+canvas.getSaveCount()+" id2:"+id2); int id3 = canvas.saveLayerAlpha(0,0,getWidth(),getHeight(),0xf0,Canvas.ALL_SAVE_FLAG); canvas.clipRect(200,200,600,600); canvas.drawColor(Color.YELLOW); Log.d(TAG,"count:"+canvas.getSaveCount()+" id3:"+id3); int id4 = canvas.save(Canvas.ALL_SAVE_FLAG); canvas.clipRect(300,300,500,500); canvas.drawColor(Color.BLUE); Log.d(TAG,"count:"+canvas.getSaveCount()+" id4:"+id4); canvas.restoreToCount(id3); canvas.drawColor(Color.GRAY); Log.d(TAG,"count:"+canvas.getSaveCount()); }我們在最後添加上canvas.restoreToCount(id3);,然後把畫布整個繪成灰色。
Log日志如下:
從代碼中可以看出調用canvas.restoreToCount(id3)後,將恢復到生成id3之前的畫布狀態,id3之前的畫布狀態就是(100,100,700,700)
public class RestoreToCountView extends View { private Paint mPaint; private String TAG = "qijian"; public RestoreToCountView(Context context, AttributeSet attrs) { super(context, attrs); setLayerType(View.LAYER_TYPE_SOFTWARE, null); mPaint = new Paint(); mPaint.setColor(Color.RED); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.save(); Log.d(TAG,"count:"+canvas.getSaveCount()); canvas.save(Canvas.ALL_SAVE_FLAG); Log.d(TAG,"count:"+canvas.getSaveCount()); canvas.saveLayer(0,0,getWidth(),getHeight(),mPaint,Canvas.CLIP_SAVE_FLAG); Log.d(TAG,"count:"+canvas.getSaveCount()); canvas.saveLayer(0,0,getWidth(),getHeight(),mPaint,Canvas.MATRIX_SAVE_FLAG); Log.d(TAG,"count:"+canvas.getSaveCount()); canvas.saveLayer(0,0,getWidth(),getHeight(),mPaint,Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); Log.d(TAG,"count:"+canvas.getSaveCount()); canvas.saveLayer(0,0,getWidth(),getHeight(),mPaint,Canvas.ALL_SAVE_FLAG); Log.d(TAG,"count:"+canvas.getSaveCount()); } }在這個例子中,我們多次調用不同的save函數和不同的FLAG,然後將棧中層數打出來,日志如下:
從效果圖中可以明顯看出,每save一次,棧的層數都在加一,所以無論哪種save方法,哪個FLAG標識,保存畫布時都使用的是同一個棧
所以restore()與restoreToCount(int count)的結論來了:
1、restore的意義是把回退棧中的最上層畫布狀態出棧,恢復畫布狀態。restoreToCount(int count)的意義是一直退棧,直到指定層count做為棧頂,將此之前的所有動作都恢復。
2、所以無論哪種save方法,哪個FLAG標識,保存畫布時都使用的是同一個棧
3、restore()與restoreToCount(int count)針對的都是同一個棧,所以是完全可以通用和混用的。
好了,有關保存圖層的知識到這裡就結束了,這兩篇內容理解起來可能會比較困難,多看兩遍喽,有關FLAG標識的知識,如果看不懂就算了,會用ALL_SAVE_FLAG就行,其它標識用到的機會比較少。如果有機會開視頻教程的話,再給大家具體演示一下,應該會比較好理解,暫且期待下吧。
概述作為一名Android開發人員,每天使用最多的類中,恐怕Context可以排的上一號了。因為Context對象在我們的項目中實在是太常見了,我們在加載資源,啟動Act
Android studio詳解我們古人又雲:工欲善其事,必先利其器。1、android studio的背景Android Studio 是一個Android開發環境,基
1.Activity類控件(1)ListActivity控件1)ListActivity控件概述ListActivity可以用來實現列表功能。在android中,List
以下開始介紹這次的面試經過:慣例:首先是HR人員上場,填寫標准制式的表格,填寫完成後,一般都是自我介紹下,這裡不再累述,干過幾個公司,為什麼離職,對本公司的了解,然後就是