編輯:關於Android編程
適用於android 開發。是一個簡單的聊天軟件,包括知識點,各個控件的運用(ExpandableListView,ViewPager,Spinner,LinearLayout,RelativeLayot),自定義的ViaImageView(自定義xml屬性),sql 的寫入,讀取等操作。
1. ViaImageView.java
package com.farina.farinaimagelib; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.RectF; import android.graphics.Xfermode; import android.graphics.drawable.Drawable; import android.graphics.drawable.NinePatchDrawable; import android.util.AttributeSet; import android.widget.ImageView; /** * Created by FarinaZhang on 2016/5/25. */ public class ViaImageView extends ImageView { private int shapeType=-1; private int borderWidth=0; //the image 's border width private int borderColor= Color.BLACK; //the image 's border color private boolean useDefaultStyle =false; //draw a common imageview private static final Xfermode MASK_XFERMODE; private int AnimType=-1; //動畫類型 private int mWidth; //圖片的寬度 private int mHeight; //圖片的高度 static { PorterDuff.Mode localMode = PorterDuff.Mode.DST_IN; MASK_XFERMODE = new PorterDuffXfermode(localMode); } public static enum Shape {circle,triangle,star,hexagonal,rectangle}; public ViaImageView(Context context){ super(context); init(context, null, 0); } public ViaImageView(Context context, AttributeSet attrs){ super(context, attrs); init(context, attrs, 0); } public ViaImageView(Context context,AttributeSet attrs,int defStyle){ super(context, attrs, defStyle); init(context, attrs, defStyle); } public void init(Context context,AttributeSet attrs,int defStyle){ if(attrs!=null){ TypedArray a = getContext().obtainStyledAttributes( attrs,R.styleable.viaImage, defStyle, 0); shapeType = (int)a.getInteger(R.styleable.viaImage_shapeType,shapeType); borderWidth=(int)a.getDimension(R.styleable.viaImage_borderWidth,borderWidth); borderColor = a.getColor(R.styleable.viaImage_borderColor, borderColor); a.recycle(); } } /** *外部接口 *設置ImageView的屬性,包括形狀,邊框顏色,邊框寬度 **/ public void setImageViewProperty(int shapeType,int width,int color){ this.shapeType = shapeType; this.borderWidth = width; this.borderColor = color; postInvalidate(); } public void setImageViewShape(int shapeType){ this.shapeType = shapeType; postInvalidate(); } public void setImageBorderWidth(int width){ this.borderWidth = width; postInvalidate(); } public void setImageBorderColor(int color){ this.borderColor = color; postInvalidate(); } /** 外部接口 * 設置是否以默認格式繪制,普通格式 */ public void setDrawCommonImage(boolean isCommon){ this.useDefaultStyle=isCommon; } @Override protected void onDraw(Canvas canvas){ if(useDefaultStyle){ super.onDraw(canvas); return; } final Drawable localDrawable=getDrawable(); if(localDrawable==null)return; if(localDrawable instanceof NinePatchDrawable)return; mWidth=getWidth(); mHeight=getHeight(); int layer=canvas.saveLayer(0.0f,0.0f,mWidth,mHeight,null,Canvas.ALL_SAVE_FLAG); localDrawable.setBounds(0,0,mWidth,mHeight); /*將drawable綁定到bitmap(this.mask)上面(drawable 只能通過bitmap顯示出來)*/ localDrawable.draw(canvas); createShapeBitmap(canvas); /*將畫布復制到layer上*/ canvas.restoreToCount(layer); if(borderWidth!=0){ drawBorder(canvas); } } private void createShapeBitmap(Canvas canvas){ Paint mypaint; mypaint = new Paint(); mypaint.setFilterBitmap(false); mypaint.setAntiAlias(true); mypaint.setXfermode(MASK_XFERMODE); Bitmap.Config localConfig=Bitmap.Config.ARGB_8888; Bitmap localBitmap=Bitmap.createBitmap(mWidth,mHeight,localConfig); Canvas localCanvas=new Canvas(localBitmap); Paint localPaint = new Paint(); localPaint.setAntiAlias(true); int padding=borderWidth; int radius = ((mWidth>mHeight)?mHeight:mWidth)/2-padding; switch(shapeType){ case 0://圓形; { localCanvas.drawCircle(mWidth/2,mHeight/2, radius, localPaint); break; } case 1://三角形; { Path path = new Path(); path.moveTo(padding, padding); path.lineTo(mWidth / 2, (float)(mWidth*Math.cos(degree2Radian(30))-padding)); path.lineTo(mWidth-padding, padding); path.close(); localCanvas.drawPath(path, localPaint); break; } case 2://五角星形; { Path path = new Path(); float radian = degree2Radian(36);// 36為五角星的角度 float radius_in = (float) (radius * Math.sin(radian / 2) / Math .cos(radian)); // 中間五邊形的半徑 path.moveTo((float) (radius * Math.cos(radian / 2)), 0);// 此點為多邊形的起點 path.lineTo((float) (radius * Math.cos(radian / 2) + radius_in * Math.sin(radian)), (float) (radius - radius * Math.sin(radian / 2))); path.lineTo((float) (radius * Math.cos(radian / 2) * 2), (float) (radius - radius * Math.sin(radian / 2))); path.lineTo((float) (radius * Math.cos(radian / 2) + radius_in * Math.cos(radian / 2)), (float) (radius + radius_in * Math.sin(radian / 2))); path.lineTo( (float) (radius * Math.cos(radian / 2) + radius * Math.sin(radian)), (float) (radius + radius * Math.cos(radian))); path.lineTo((float) (radius * Math.cos(radian / 2)), (float) (radius + radius_in)); path.lineTo( (float) (radius * Math.cos(radian / 2) - radius * Math.sin(radian)), (float) (radius + radius * Math.cos(radian))); path.lineTo((float) (radius * Math.cos(radian / 2) - radius_in * Math.cos(radian / 2)), (float) (radius + radius_in * Math.sin(radian / 2))); path.lineTo(0, (float) (radius - radius * Math.sin(radian / 2))); path.lineTo((float) (radius * Math.cos(radian / 2) - radius_in * Math.sin(radian)), (float) (radius - radius * Math.sin(radian / 2))); path.close();// 使這些點構成封閉的多邊形 localCanvas.drawPath(path, localPaint); break; } case 3://正六邊形; { Path path= new Path(); float radian = degree2Radian(30); path.moveTo((float)(radius*Math.sin(radian)), 0); path.lineTo((float)(radius*Math.sin(radian)+radius), 0); path.lineTo((float)(2*radius), (float)(radius*Math.cos(radian)) ); path.lineTo((float)(radius*Math.sin(radian)+radius),(float)(2*(radius*Math.cos(radian)))); path.lineTo((float)(radius*Math.sin(radian)),(float)(2*(radius*Math.cos(radian)))); path.lineTo(0,(float)(radius*Math.cos(radian))); path.close(); localCanvas.drawPath(path,localPaint); break; } default://方形 { int realWidth = (mWidth>mHeight)?mHeight:mWidth; int x = padding +(mWidth-realWidth)/2; int y = padding +(mHeight-realWidth)/2; RectF localRectF=new RectF(x, y, realWidth-padding*2, realWidth-padding*2); localCanvas.drawRect(localRectF, localPaint); break; } } /*將bitmap 畫到canvas上*/ canvas.drawBitmap(localBitmap,0.0f,0.0f,mypaint); } //畫邊框 private void drawBorder(Canvas canvas){ Paint localPaint = new Paint(); localPaint.setColor(borderColor); localPaint.setStyle(Paint.Style.STROKE); localPaint.setStrokeWidth(borderWidth); localPaint.setAntiAlias(true); int radius=((mWidth>mHeight)?mHeight:mWidth)/2-borderWidth/2; int padding = borderWidth/2; switch(shapeType){ case 0://圓形; { canvas.drawCircle(mWidth/2, mHeight/2,radius,localPaint); break; } case 1://三角形; { Path path = new Path(); path.moveTo(padding, padding); path.lineTo(mWidth / 2, (float)(mWidth*Math.cos(degree2Radian(30))-padding)); path.lineTo(mWidth-padding, padding); path.close(); canvas.drawPath(path, localPaint); break; } case 2://五角星形; { Path path = new Path(); float radian = degree2Radian(36);// 36為五角星的角度 float radius_in = (float) (radius * Math.sin(radian / 2) / Math .cos(radian)); // 中間五邊形的半徑 path.moveTo((float) (radius * Math.cos(radian / 2)), 0);// 此點為多邊形的起點 path.lineTo((float) (radius * Math.cos(radian / 2) + radius_in * Math.sin(radian)), (float) (radius - radius * Math.sin(radian / 2))); path.lineTo((float) (radius * Math.cos(radian / 2) * 2), (float) (radius - radius * Math.sin(radian / 2))); path.lineTo((float) (radius * Math.cos(radian / 2) + radius_in * Math.cos(radian / 2)), (float) (radius + radius_in * Math.sin(radian / 2))); path.lineTo( (float) (radius * Math.cos(radian / 2) + radius * Math.sin(radian)), (float) (radius + radius * Math.cos(radian))); path.lineTo((float) (radius * Math.cos(radian / 2)), (float) (radius + radius_in)); path.lineTo( (float) (radius * Math.cos(radian / 2) - radius * Math.sin(radian)), (float) (radius + radius * Math.cos(radian))); path.lineTo((float) (radius * Math.cos(radian / 2) - radius_in * Math.cos(radian / 2)), (float) (radius + radius_in * Math.sin(radian / 2))); path.lineTo(0, (float) (radius - radius * Math.sin(radian / 2))); path.lineTo((float) (radius * Math.cos(radian / 2) - radius_in * Math.sin(radian)), (float) (radius - radius * Math.sin(radian / 2))); path.close();// 使這些點構成封閉的多邊形 canvas.drawPath(path, localPaint); break; } case 3://正六邊形; { Path path= new Path(); float radian = degree2Radian(30); path.moveTo((float)(radius*Math.sin(radian)), 0); path.lineTo((float)(radius*Math.sin(radian)+radius), 0); path.lineTo((float)(2*radius), (float)(radius*Math.cos(radian)) ); path.lineTo((float)(radius*Math.sin(radian)+radius),(float)(2*(radius*Math.cos(radian)))); path.lineTo((float)(radius*Math.sin(radian)),(float)(2*(radius*Math.cos(radian)))); path.lineTo(0,(float)(radius*Math.cos(radian))); path.close(); canvas.drawPath(path,localPaint); break; } default://方形 { int realWidth = (mWidth>mHeight)?mHeight:mWidth-borderWidth; int x = padding +(mWidth-realWidth)/2; int y = padding +(mHeight-realWidth)/2; RectF localRectF=new RectF(x, y, realWidth-padding*2, realWidth-padding*2); canvas.drawRect(localRectF, localPaint); break; } } } //將角度轉化為弧度 private float degree2Radian(int degree) { // TODO Auto-generated method stub return (float) (Math.PI * degree / 180); } }
2. ContactExpendListAdapter.java
package com.farina.adapter; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseExpandableListAdapter; import android.widget.ImageView; import android.widget.TextView; import com.farina.data.FriendEntity; import com.farina.data.FriendListData; import com.farina.farinaimagelib.ViaImageView; import com.farina.libtest.R; import java.util.List; /** * Created by FarinaZhang on 2016/7/5. */ public class ContactExpendListAdapter extends BaseExpandableListAdapter { private Context mContext; private List<FriendListData> mListData; public ContactExpendListAdapter(Context context, List<FriendListData> data){ mContext = context; mListData = data; } @Override public int getGroupCount(){ return mListData.size(); } @Override public int getChildrenCount(int groupPosition){ return mListData.get(groupPosition).getFriendChildList().size(); } @Override public Object getGroup(int groupPosition){ return mListData.get(groupPosition).getGroupName(); } @Override public Object getChild(int groupPosition, int childPosition){ return mListData.get(groupPosition).getFriendChildList().get(childPosition); } @Override public long getGroupId(int groupPosition){ return groupPosition; } @Override public long getChildId(int groupPosition, int childPosition){ return childPosition; } @Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent){ groupHolder viewHolder =null; if(convertView == null){ convertView = LayoutInflater.from(mContext).inflate(R.layout.contact_list_group, null); viewHolder = new groupHolder(); viewHolder.icon = (ImageView)convertView.findViewById(R.id.icon); viewHolder.groupName = (TextView)convertView.findViewById(R.id.goup_name); convertView.setTag(viewHolder); }else{ viewHolder = (groupHolder)convertView.getTag(); } viewHolder.groupName.setText(mListData.get(groupPosition).getGroupName()); if(isExpanded){ viewHolder.icon.setImageResource(R.mipmap.arrow_down); }else{ viewHolder.icon.setImageResource(R.mipmap.arrow_up); } return convertView; } @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent){ memberHolder viewHolder = null; if(convertView == null){ convertView = LayoutInflater.from(mContext).inflate(R.layout.contact_list_member, null); viewHolder= new memberHolder(); viewHolder.memberImg = (ViaImageView) convertView.findViewById(R.id.member_img); viewHolder.memberName = (TextView)convertView.findViewById(R.id.member_name); convertView.setTag(viewHolder); }else{ viewHolder =(memberHolder)convertView.getTag(); } FriendEntity entity= mListData.get(groupPosition).getFriendChildList().get(childPosition); String icnPath = entity.getIcnPath(); if(icnPath == null||icnPath.length()<=0) { viewHolder.memberImg.setImageDrawable(mContext.getResources().getDrawable(R.mipmap.user_img)); } viewHolder.memberName.setText(entity.getName()); return convertView; } @Override public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } @Override public boolean hasStableIds(){ return true; } private class memberHolder{ ViaImageView memberImg; TextView memberName; } private class groupHolder{ ImageView icon; TextView groupName; } }
3. ChatInfoManager.java
package com.farina.db; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import com.farina.data.FriendEntity; import com.farina.data.FriendListData; import com.farina.data.GroupEntity; import com.farina.data.MessageEntity; import com.farina.data.UserEntity; import java.util.ArrayList; import java.util.List; /** * Created by FarinaZhang on 2016/7/14. */ public class ChatInfoManager { private Context mContext; private ChatDBhelper mDBHelper; //table user string private final String USER_TABLE_NAME="users"; private final String USER_ID="id"; private final String USER_COUNT_NUMBER="countNumber"; private final String USER_NIKENAME="nikeName"; private final String USER_ICON_PATH="iconPath"; private final String USER_PHONE_NUMBER="phoneNumber"; private final String USER_MAIL_ADDR="mailAddr"; private final String USER_QQ_NUMBER="qqNumber"; private final String USER_WEIXIN_NUMBER="weixinNumber"; //table friends string private final String FRIEND_TABLE_NAME="friends"; private final String FRIEND_ID="id"; private final String FRIEND_HOST_ID="hostId"; private final String FRIEND_GROUP_ID="groupId"; private final String FRIEND_NAME="friendName"; private final String FRIEND_ICON_PATH="iconPath"; private final String FRIEND_BELIVE="beLive"; //table groups string private final String GROUP_TABLE_NAME="groups"; private final String GROUP_ID="id"; private final String GROUP_HOST_ID="hostId"; private final String GROUP_NAME="groupName"; //table messages string private final String MESSAGE_TABLE_NAME="messages"; private final String MESSAGE_ID="id"; private final String MESSAGE_MESSAGE="message"; private final String MESSAGE_FROM_ID="fromId"; private final String MESSAGE_TO_ID="toId"; private final String MESSAGE_READED="readed"; private final String MESSAGE_TYPE="type"; private final String MESSAGE_TIME="time"; public ChatInfoManager(Context context){ mContext = context; mDBHelper = ChatDBhelper.getInstance(mContext); } public void addUser(UserEntity user){ SQLiteDatabase db = null; try { db = mDBHelper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(USER_ID,user.getId()); values.put(USER_COUNT_NUMBER,user.getCountNumber()); values.put(USER_NIKENAME,user.getNikeName()); values.put(USER_ICON_PATH,user.getIconPath()); values.put(USER_PHONE_NUMBER,user.getPhoneNumber()); values.put(USER_MAIL_ADDR,user.getMailNumber()); values.put(USER_QQ_NUMBER,user.getQQNumber()); values.put(USER_WEIXIN_NUMBER,user.getWeixinNumber()); db.insert(USER_TABLE_NAME, null, values); } catch (Exception e) { e.printStackTrace(); // TODO: handle exception } finally { db.close(); } } public UserEntity getUserData(int index){ UserEntity user= new UserEntity(); SQLiteDatabase db =null; Cursor cursor = null; try { db = mDBHelper.getReadableDatabase(); cursor = db.query(USER_TABLE_NAME, null, USER_ID + "=" + index, null, null, null, null); if (cursor != null) { user.setId(index); user.setCountNumber(cursor.getString(cursor.getColumnIndex(USER_COUNT_NUMBER))); user.setNikeName(cursor.getString(cursor.getColumnIndex(USER_NIKENAME))); user.setIconPath(cursor.getString(cursor.getColumnIndex(USER_ICON_PATH))); user.setPhoneNumber(cursor.getString(cursor.getColumnIndex(USER_PHONE_NUMBER))); user.setMailNumber(cursor.getString(cursor.getColumnIndex(USER_MAIL_ADDR))); user.setQQNumber(cursor.getString(cursor.getColumnIndex(USER_QQ_NUMBER))); user.setWeixinNumber(cursor.getString(cursor.getColumnIndex(USER_WEIXIN_NUMBER))); } else { return null; } }catch (Exception e){ e.printStackTrace(); }finally{ db.close(); } return user; } public List<UserEntity> getUserList(){ List<UserEntity> list =new ArrayList<UserEntity>(); SQLiteDatabase db =null; Cursor cursor=null; try{ db=mDBHelper.getReadableDatabase(); cursor=db.query(USER_TABLE_NAME,new String[]{USER_ID,USER_COUNT_NUMBER,USER_NIKENAME,USER_ICON_PATH},null,null,null,null,null); if(cursor!=null){ while (cursor.moveToNext()) { UserEntity user= new UserEntity(); user.setId(cursor.getInt(cursor.getColumnIndex(USER_ID))); user.setCountNumber(cursor.getString(cursor.getColumnIndex(USER_COUNT_NUMBER))); user.setNikeName(cursor.getString(cursor.getColumnIndex(USER_NIKENAME))); user.setIconPath(cursor.getString(cursor.getColumnIndex(USER_ICON_PATH))); list.add(user); } } }catch(Exception e){ e.printStackTrace(); }finally{ db.close(); } return list; } public void addFriend(FriendEntity friend){ SQLiteDatabase db=null; try{ db=mDBHelper.getWritableDatabase(); if(db==null)return ; ContentValues values = new ContentValues(); values.put(FRIEND_ID,friend.getId()); values.put(FRIEND_HOST_ID,friend.getHostId()); values.put(FRIEND_GROUP_ID,friend.getgroupId()); values.put(FRIEND_NAME,friend.getName()); values.put(FRIEND_ICON_PATH,friend.getIcnPath()); values.put(FRIEND_BELIVE,friend.getBeLive()); db.insert(FRIEND_TABLE_NAME,null,values); }catch(Exception e){ e.printStackTrace(); }finally { db.close(); } } public List<FriendListData> getFriendList(){ SQLiteDatabase db=null; List<FriendListData> friendList=new ArrayList<FriendListData>(); List<GroupEntity> groupList= getGroupList(); try{ db = mDBHelper.getWritableDatabase(); if (db == null) return null; for(int i=0;i<groupList.size();i++) { FriendListData friendGroup= new FriendListData(); String groupName = groupList.get(i).getName(); friendGroup.setGroupName(groupName); List<FriendEntity> groupChild=new ArrayList<FriendEntity>(); Cursor cursor = db.query(FRIEND_TABLE_NAME, null, GROUP_NAME+"="+groupName, null, null, FRIEND_ID + "ASC", null); while (cursor.moveToNext()) { FriendEntity entity = new FriendEntity(); entity.setId(cursor.getInt(cursor.getColumnIndex(FRIEND_ID))); entity.setgroupId(cursor.getInt(cursor.getColumnIndex(FRIEND_GROUP_ID))); entity.setHostId(cursor.getInt(cursor.getColumnIndex(FRIEND_HOST_ID))); entity.setName(cursor.getString(cursor.getColumnIndex(FRIEND_NAME))); entity.setIcnPath(cursor.getString(cursor.getColumnIndex(FRIEND_ICON_PATH))); String beLive = cursor.getString(cursor.getColumnIndex(FRIEND_BELIVE)); entity.setBeLive(beLive.equals("1")); groupChild.add(entity); } friendGroup.setFriendChildList(groupChild); friendList.add(friendGroup); } }catch(Exception e){ e.printStackTrace(); }finally { db.close(); } return friendList; } public List<GroupEntity> getGroupList(){ List<GroupEntity> groupList = null; SQLiteDatabase db=null; try{ db= mDBHelper.getReadableDatabase(); Cursor cursor =db.query(GROUP_TABLE_NAME,null,null,null,null,null,null); while(cursor.moveToNext()){ GroupEntity entity =new GroupEntity(); entity.setId(cursor.getInt(cursor.getColumnIndex(GROUP_ID))); entity.setHostId(cursor.getInt(cursor.getColumnIndex(GROUP_HOST_ID))); entity.setGroupName(cursor.getString(cursor.getColumnIndex(GROUP_NAME))); groupList.add(entity); } }catch(Exception e){ e.printStackTrace(); }finally{ db.close(); } return groupList; } public void addGroupMember(GroupEntity group){ SQLiteDatabase db=null; try{ db=mDBHelper.getWritableDatabase(); ContentValues values=new ContentValues(); values.put(GROUP_ID,group.getId()); values.put(GROUP_HOST_ID,group.getHostId()); values.put(GROUP_NAME,group.getName()); db.insert(GROUP_TABLE_NAME,null,values); }catch(Exception e){ e.printStackTrace(); }finally { db.close(); } } public List<MessageEntity> getMessageList(String loadId){ List<MessageEntity> list = new ArrayList<MessageEntity>(); SQLiteDatabase db=null; Cursor cursor=null; try{ db=mDBHelper.getReadableDatabase(); cursor=db.query(MESSAGE_TABLE_NAME,null, MESSAGE_FROM_ID+"=?,"+MESSAGE_TO_ID+"=?", new String[]{loadId}, null, loadId,MESSAGE_TIME+"DES",null); while(cursor.moveToNext()){ MessageEntity entity =new MessageEntity(); entity.setId(cursor.getInt(cursor.getColumnIndex(MESSAGE_ID))); entity.setFromId(cursor.getInt(cursor.getColumnIndex(MESSAGE_FROM_ID))); entity.setToId(cursor.getInt(cursor.getColumnIndex(MESSAGE_TO_ID))); entity.setMessageStr(cursor.getString(cursor.getColumnIndex(MESSAGE_MESSAGE))); entity.setType(cursor.getString(cursor.getColumnIndex(MESSAGE_TYPE))); entity.setTime(cursor.getString(cursor.getColumnIndex(MESSAGE_TIME))); list.add(entity); } }catch (Exception e){ e.printStackTrace(); }finally{ db.close(); } return list; } public void setMessageItem(MessageEntity message){ SQLiteDatabase db=null; try{ db=mDBHelper.getWritableDatabase(); if(db==null)return; ContentValues values = new ContentValues(); values.put(MESSAGE_ID,message.getId()); values.put(MESSAGE_FROM_ID,message.getFromId()); values.put(MESSAGE_TO_ID,message.getToId()); values.put(MESSAGE_MESSAGE,message.getMessageStr()); values.put(MESSAGE_TYPE,message.getType()); values.put(MESSAGE_TIME,message.getTime()); db.insert(MESSAGE_TABLE_NAME,null,values); }catch(Exception e){ e.printStackTrace(); }finally { db.close(); } } }
源碼下載地址
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。
我們知道,在Android系統中,Activity是以堆棧的形式組織在ActivityManagerService服務中的。與Activity類似,Android系統中的
目錄:1.重要類概述2.重要類的常用方法2.簡單View繪制(圓、圓弧、矩形、弧形、圓角矩形、橢圓、文字等)3.setXfermode(Xfermode xfermode
若有這樣的需求或場景,要求每次啟動Activity時都清空原有的任務棧,也就是finish掉原任務棧中的所有Activity,有沒有一種鸠占鵲巢的趕腳?下面介紹的這個方法
OpenGL ESAndroid包括高性能2D和3D圖形開放圖形庫(OpenGL?的),具體而言,OpenGL ES的API支持。 OpenGL是一個跨平台的圖形API,