1.Bitmap和BitmapFactory
创建assets文件夹(app文件夹下右键new folder/assets folder)
public class MainActivity extends AppCompatActivity {
private ImageView myimg;
private Button mybut;
private String[] images;
private int currentImg=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myimg=findViewById(R.id.myimg);
mybut=findViewById(R.id.mybut);
try {
images=getAssets().list("");
} catch (IOException e) {
e.printStackTrace();
}
mybut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//当数组越界
if (currentImg>images.length){
currentImg=0;
}
//找到下一张图片
while (!images[currentImg].endsWith(".png") &&
!images[currentImg].endsWith(".jpg") &&
!images[currentImg].endsWith(".gif")
){
currentImg++;
if (currentImg>images.length){
currentImg=0;
}
}
InputStream assetFile=null;
try {
assetFile=getAssets().open(images[currentImg++]);
} catch (IOException e) {
e.printStackTrace();
}
//从图片控件拿bitmapDrawable对象
BitmapDrawable bitmapDrawable=(BitmapDrawable)myimg.getDrawable();
//从内存中回收
if (bitmapDrawable!=null && !bitmapDrawable.getBitmap().isRecycled()){
bitmapDrawable.getBitmap().recycle();
}
//从文件流中创建位图并设置在图形控件上
myimg.setImageBitmap(BitmapFactory.decodeStream(assetFile));
}
});
}
}
2.绘画基础:paint,Canvas
实际上是自定义一个View类
1、创建自己的View类并继承View类
public class MyView extends View {
private Path path =new Path();
public MyView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
Paint paint=new Paint();
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setAntiAlias(true);
paint.setColor(Color.BLUE);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(4f);
int viewWith=this.getWidth();
//canvas.drawCircle(viewWith/10+10,viewWith/10+10,viewWith/10,paint);
//canvas.drawRect(555,255,955,1055,paint);
path.moveTo(100f,viewWith*9/10+60);
path.lineTo(viewWith/5+10,viewWith*9/10+60);
path.lineTo(viewWith/5+10,viewWith*7/10+60);
path.close();
canvas.drawPath(path,paint);
}
}
2、activity文件
public class MainActivity extends AppCompatActivity {
private LinearLayout myll;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyView myView=new MyView(this,null);
myll=findViewById(R.id.myll);
myll.addView(myView);
}
}
3.path类:绘制路径
public class MainActivity extends AppCompatActivity {
private LinearLayout myll;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyView(this));
//MyView oneView=new MyView(this);
//myll.addView(oneView);
}
public class MyView extends View {
private float phase;
private PathEffect[] effects=new PathEffect[7];
private int[] colors;
private Paint paint=new Paint();
//初始化path
private android.graphics.Path path=new Path();
public MyView(Context context) {
super(context);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(4f);
path.moveTo(0f,0f);
for (int i=1;i<=40;i++){
//生成40个随机点(y值随机),并将其连成一线
path.lineTo(i*25f,(float) Math.random()*90);
}
//初始化7种颜色
colors=new int[]{Color.BLACK,Color.BLUE,Color.CYAN,Color.GRAY,Color.GREEN,Color.MAGENTA,Color.RED,Color.YELLOW};
//以下各种效果
effects[0]=null;
effects[1]=new CornerPathEffect(10f);
effects[2]=new DiscretePathEffect(3.0f,5.0f);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//背景填充
canvas.drawColor(Color.WHITE);
canvas.translate(8f,8f);
for(int i=0;i<effects.length;i++){
paint.setPathEffect(effects[i]);
paint.setColor(colors[i]);
canvas.drawPath(path,paint);
canvas.translate(0f,90f);
}
effects[3]=new DashPathEffect(new float[]{20f,10f,5f,10f},phase);
Path p=new Path();
p.addRect(0f,0f,8f,8f,Path.Direction.CCW);
effects[4]=new PathDashPathEffect(p,12f,phase,PathDashPathEffect.Style.ROTATE);
effects[5]=new ComposePathEffect(effects[2],effects[4]);
effects[6]=new SumPathEffect(effects[4],effects[3]);
phase+=1f;
invalidate();
}
}
}
4.path类:文本跟随路径
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new PathTextView(this));
}
public static class PathTextView extends View {
private String drawStr=getResources().getString(R.string.draw_string);
private Path[] paths=new Path[3];
private Paint paint=new Paint();
public PathTextView(Context context) {
super(context);
paths[0]=new Path();
paths[0].moveTo(0f,0f);
for (int i=1;i<=20;i++){
//随机生成20个点,并连成一线
paths[0].lineTo(i*30f,(float)(Math.random())*30);
}
paths[1]=new Path();
RectF rectF=new RectF(0f,0f,600f,360f);
paths[1].addOval(rectF,Path.Direction.CCW);
paths[2]=new Path();
paths[2].addArc(rectF,60f,180f);
//初始化画笔
paint.setAntiAlias(true);
paint.setColor(Color.BLUE);
paint.setStrokeWidth(1f);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.WHITE);
canvas.translate(40f,40f);
//设置从右边开始绘制(右对齐)
paint.setTextAlign(Paint.Align.RIGHT);
paint.setTextSize(30f);
//绘制路径
paint.setStyle(Paint.Style.STROKE);
canvas.drawPath(paths[0],paint);
paint.setTextSize(40f);
//沿着路径绘制一段文本
paint.setStyle(Paint.Style.FILL);
canvas.drawTextOnPath(drawStr,paths[0],-8f,20f,paint);
canvas.translate(0f,60f);
paint.setStyle(Paint.Style.STROKE);
canvas.drawPath(paths[1],paint);
paint.setStyle(Paint.Style.FILL);
canvas.drawTextOnPath(drawStr,paths[1],-20f,20f,paint);
canvas.translate(0f,360f);
paint.setStyle(Paint.Style.STROKE);
canvas.drawPath(paths[2],paint);
paint.setStyle(Paint.Style.FILL);
canvas.drawTextOnPath(drawStr,paths[2],-10f,20f,paint);
}
}
}
资源文件
<resources>
<string name="app_name">MyEX136Path</string>
<string name="draw_string">疯狂android讲义</string>
</resources>
效果:
5.path类:双缓冲实现画图板
1创建string字符串资源
<resources>
<string name="app_name">MyEX137Duplicate</string>
<string name="color">颜色</string>
<string name="color_red">红色</string>
<string name="color_green">绿色</string>
<string name="color_blue">蓝色</string>
<string name="width">宽度</string>
<string name="width_1">低宽度</string>
<string name="width_2">中宽度</string>
<string name="width_3">大宽度</string>
<string name="blur">blur</string>
<string name="emboss">emboss</string>
</resources>
2创建menu菜单资源
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="@string/color">
<menu>
<group android:checkableBehavior="single">
<item android:id="@+id/red" android:title="@string/color_red"/>
<item android:id="@+id/green" android:title="@string/color_green"/>
<item android:id="@+id/blue" android:title="@string/color_blue"/>
</group>
</menu>
</item>
<item android:title="@string/width">
<menu>
<group>
<item android:id="@+id/width_1" android:title="@string/width_1"/>
<item android:id="@+id/width_2" android:title="@string/width_2"/>
<item android:id="@+id/width_3" android:title="@string/width_3"/>
</group>
</menu>
</item>
<item android:id="@+id/blur" android:title="@string/blur"/>
<item android:id="@+id/emboss" android:title="@string/emboss"/>
</menu>
3、创建DrawView自定义类,继承View
public class DrawView extends View {
private float preX,preY;
private Path path;
public Paint paint=null;
//定义一个缓冲图片
Bitmap cacheBitmap=null;
//定义一个缓冲画布用于装载缓冲图片
Canvas cacheCanvas=null;
public DrawView(Context context,int width,int height) {
super(context);
//创建一个与该View具有相同大小的缓冲区
cacheBitmap=Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);
cacheCanvas=new Canvas();
path=new Path();
//设置cacheCanvas将会绘制到内存中的cacheBitmap上
cacheCanvas.setBitmap(cacheBitmap);
//设置画笔的颜色
paint=new Paint(Paint.DITHER_FLAG);
paint.setColor(Color.RED);
//设置画笔风格
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(1);
//反锯齿
paint.setAntiAlias(true);
paint.setDither(true);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//获取拖动事件的发生位置
float x=event.getX();
float y=event.getY();
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
//从前一个点绘制到当前点之后,把当前点定义称为下次绘制的前一个点
path.moveTo(x,y);
preX=x;
preY=y;
break;
case MotionEvent.ACTION_MOVE:
//从前一个点绘制到当前点之后,把当前点定义称为下次绘制的前一个点
path.quadTo(preX,preY,x,y);
preX=x;
preY=y;
break;
case MotionEvent.ACTION_UP:
cacheCanvas.drawPath(path,paint);
path.reset();
break;
}
invalidate();
return true;
}
@Override
protected void onDraw(Canvas canvas) {
Paint bmpPaint=new Paint();
//将cacheBitmap会知道view组件上
canvas.drawBitmap(cacheBitmap,0,0,bmpPaint);
//沿着path绘制
canvas.drawPath(path,paint);
}
}
4activity文件
public class MainActivity extends AppCompatActivity {
EmbossMaskFilter emboss;
BlurMaskFilter blur;
DrawView drawView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout linearLayout=new LinearLayout(this);
DisplayMetrics displayMetrics=new DisplayMetrics();
//获取创建的宽度和高度
getWindowManager().getDefaultDisplay().getRealMetrics(displayMetrics);
//创建一个drawview,该drawview的高度与宽度与activity相同
drawView=new DrawView(this,displayMetrics.widthPixels,displayMetrics.heightPixels);
linearLayout.addView(drawView);
setContentView(linearLayout);
emboss=new EmbossMaskFilter(new float[]{1.5f,1.5f,1.5f},0.6f,6,4.2f);
blur=new BlurMaskFilter(8,BlurMaskFilter.Blur.NORMAL);
}
//创建can带选项
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater=new MenuInflater(this);
//加载自定义的菜单,并添加到menu中去
inflater.inflate(R.menu.menu_main,menu);
return super.onCreateOptionsMenu(menu);
}
//菜单被单击后的回调方法
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.red:
drawView.paint.setColor(Color.RED);
item.setChecked(true);
break;
case R.id.green:
drawView.paint.setColor(Color.GREEN);
item.setChecked(true);
break;
case R.id.blue:
drawView.paint.setColor(Color.BLUE);
item.setChecked(true);
break;
case R.id.width_1:
drawView.paint.setStrokeWidth(1);
break;
case R.id.width_2:
drawView.paint.setStrokeWidth(3);
break;
case R.id.width_3:
drawView.paint.setStrokeWidth(5);
break;
case R.id.blur:
drawView.paint.setMaskFilter(blur);
break;
case R.id.emboss:
drawView.paint.setMaskFilter(emboss);
break;
}
return true;
}
}
效果
图形图像这张本例以后部分暂不学习,感觉是游戏开发的基础,不是感兴趣的方向。直接跳转到数据存储与io