Android相关
1》UI操作_Bitmap补充(图片压缩,切割,缩放,加圆角)
1_MainActivity
package
myapp.com.day26_1_bitmap;
import
android.app.Activity;
import
android.graphics.Bitmap;
import
android.graphics.BitmapFactory;
import
android.graphics.Canvas;
import
android.graphics.Color;
import
android.graphics.Paint;
import
android.graphics.PorterDuff;
import
android.graphics.PorterDuffXfermode;
import
android.graphics.RectF;
import
android.graphics.Typeface;
import
android.os.Bundle;
import
android.view.View;
import
android.widget.ImageView;
import
android.widget.TextView;
public
class
MainActivity
extends
Activity {
TextView tv;
ImageView iv;
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView)findViewById(R.id.text1);
iv = (ImageView)findViewById(R.id.iv);
//创建字体对象
// /*
// * 参数:
// * 1:获取assets文件夹管理对象
// * 2:字体文件在assets文件夹中的路径
// * */
Typeface tf = Typeface.createFromAsset(getAssets(),
"fonts/ww.TTF"
);
//设置字体
tv.setTypeface(tf);
// Bitmap bit = BitmapFactory.decodeResource(getResources(), R.mipmap.wp_009);
// iv.setImageBitmap(bit);
}
public
void
click (View v) {
switch
(v.getId()) {
case
R.id.button:
//解决图片内存溢出的方式
// /*
// * 前2个参数与之前的使用方式都是一致的
// * 参数3:Options, 该对象中有一条inSampleSize的属性
// * 该属性可以实现将图片的大小以及尺寸一起缩小指定倍数
// * */
BitmapFactory.Options options =
new
BitmapFactory.Options();
// /*
// * 当大家指定inSampleSize的属性值的时候,该属性值尽量直接指定为
// * 2的n次幂对应的数据,因为即使设置的数字不是2的n次幂,系统也会
// * 自动根据指定的数字去寻找最近的2的n次幂对应的数字
// * 即设置为7和8,最终的缩小倍数都是8倍
// *
// * */
options.inSampleSize =
8
;
Bitmap bit = BitmapFactory.decodeResource(getResources(),R.mipmap.wp_009,options);
iv.setImageBitmap(bit);
break
;
case
R.id.button2:
//当明确图片最终显示尺寸时,可以通过计算得到inSampleSize的值
// /*
// * 解决思路:
// * 为了防止在decode图片时内存溢出,又要获取图片大小
// * */
BitmapFactory.Options options1 =
new
BitmapFactory.Options();
//以下两行代码代表解析图片,但是在解析的过程中只加载图片宽高等信息,不加载具体图片
//也可理解为当以下两行代码执行完毕后,在option1对象中存储好图片的宽高
options1.inJustDecodeBounds =
true
;
BitmapFactory.decodeResource(getResources(),R.mipmap.wp_009,options1);
//获取图片宽高
int
bitW = options1.outWidth;
int
bitH = options1.outHeight;
//获取图片宽高的缩小比例, 注:记得确保图片宽肯定大于想要宽
int
scaleW = bitW /
100
;
int
scaleH = bitH /
100
;
//取出宽高中缩小比例最大的值最为最终的图片的缩小倍数
int
scale = scaleW>scaleH?scaleW:scaleH;
options1.inSampleSize = scale;
options1.inJustDecodeBounds =
false
;
Bitmap b = BitmapFactory.decodeResource(getResources(),R.mipmap.wp_009,options1);
iv.setImageBitmap(b);
break
;
case
R.id.button3:
//实现图片切割效果
//1. 获取完整图片对应的Bitmap对象
Bitmap source = BitmapFactory.decodeResource(getResources(),R.mipmap.sample_7);
//2. 通过createBitmap方法实现图片的截取
// /*
// * 1. 完整图片
// * 2,3. 根据这两个参数所指定的x,y坐标在完整范围内确定起始点
// * 4. 从起始点截取指定的宽度
// * 5. 从起始点截取指定的高度
// * 返回值: 按照指定的起始点即宽高得到的截取后的图片
// * */
Bitmap bitmap1 = Bitmap.createBitmap(source,
0
,
0
,source.getWidth()/
2
,source.getHeight()/
2
);
iv.setImageBitmap(bitmap1);
break
;
case
R.id.button4:
//图片的缩放
//1. 获取原始图片
Bitmap source1 = BitmapFactory.decodeResource(getResources(),R.mipmap.sample_7);
//2. 通过createScaledBitmap方法获取缩放后的图片
// /*
// * 1. 原始图片
// * 2. 缩放后的宽
// * 3.缩放后的高
// * 4. true, 确保图片缩放后也不会模糊
// * */
Bitmap bitmap2 = Bitmap.createScaledBitmap(source1,
500
,
600
,
true
);
iv.setImageBitmap(bitmap2);
break
;
case
R.id.button5:
//给图片添加圆角效果
Bitmap round = getRoundBitmap(BitmapFactory.decodeResource(getResources(),R.mipmap.sample_7));
iv.setImageBitmap(round);
break
;
}
}
//自定义方法,有获取圆角图片
// /*
// * 参数为原始的直角图片
// * 核心思想:绘制一个圆角矩形与直角图片,实现让两者重叠显示
// * 并且只保留圆角矩形内的图片内容
// * 剩下的就是圆角图片
// * */
public
Bitmap getRoundBitmap(Bitmap source){
//1. 创建一个与原始图片等宽等高空白的Bitmap对象
Bitmap bitmap = Bitmap.createBitmap(source.getWidth(),source.getHeight(), Bitmap.Config.ARGB_8888);
//2. 依据此空白bitmap对象创建一个Canvas对象
// 此处的作用为:当后期通过canvas对象绘制内容时,最终都会被绘制到参数bitmap对象上
//即做种得到圆角图片,存在bitmap对象中
Canvas canvas =
new
Canvas(bitmap);
//3. 创建画笔对象
Paint paint =
new
Paint();
paint.setColor(Color.RED);
//设置画笔颜色
paint.setAntiAlias(
true
);
//抗锯齿
//4. 绘制一个圆角矩形
//作为基准的直角矩形,参数1,2代表直角矩形左上角点的坐标
//参数3,4 右下角点的坐标
RectF rectF =
new
RectF(
0
,
0
,source.getWidth(),source.getHeight());
//1. 基准矩形
//2. x方法向的角度
//3. y方向的角度
canvas.drawRoundRect(rectF,
30
,
30
,paint);
//5. 设置圆角矩形与稍后绘制的直角图片的相交保留原则
paint.setXfermode(
new
PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
//6. 绘制直角图片
canvas.drawBitmap(source,
0
,
0
,paint);
return
bitmap;
}
}
2》九宫格拼图
package
myapp.com.day26_2_low;
import
android.app.Activity;
import
android.graphics.Bitmap;
import
android.graphics.BitmapFactory;
import
android.os.Bundle;
import
android.view.View;
import
android.view.ViewGroup;
import
android.widget.AdapterView;
import
android.widget.BaseAdapter;
import
android.widget.GridView;
import
android.widget.ImageView;
import
android.widget.Toast;
import
java.util.ArrayList;
import
java.util.Collections;
public
class
MainActivity
extends
Activity {
// /*
// * 实现一个简单的拼图小游戏
// * */
GridView gv;
ArrayList<Bitmap> list =
new
ArrayList<>();
PinTuAdapter adapter;
boolean
flag =
true
;
//当item被点击时,如果flag为true,记录点击位置
//如果flag为false,就交换两次点击的图片
int
lastPoi = -
1
;
String success;
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gv = (GridView) findViewById(R.id.gv);
Bitmap source = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.sample_7)
,
600
,
600
,
true
);
// /*
// * 初始化List集合中要显示的图片资源
// * */
int
w = source.getWidth() /
3
;
int
h = source.getHeight() /
3
;
for
(
int
i=
0
;i<
9
;i++) {
Bitmap bit = Bitmap.createBitmap(source,(i%
3
)*w,(i/
3
)*h,w,h);
list.add(bit);
}
success = list.toString();
adapter =
new
PinTuAdapter();
gv.setAdapter(adapter);
// /*
// * 设置让两次点击的图片相交换
// * */
gv.setOnItemClickListener(
new
AdapterView.OnItemClickListener() {
@Override
public
void
onItemClick(AdapterView<?> parent, View view,
int
position,
long
id) {
if
(flag) {
lastPoi = position;
flag =
false
;
}
else
{
Collections.swap(list, lastPoi, position);
adapter.notifyDataSetChanged();
if
(list.toString().equals(success)) {
Toast.makeText(MainActivity.
this
,
"恭喜你!!成功了!!!"
, Toast.LENGTH_SHORT).show();
}
flag =
true
;
}
}
});
}
public
void
click (View v){
//打乱方式一
Collections.shuffle(list);
//打乱方式二,swap交换100次
// Collections.swap(list,4,5);
adapter.notifyDataSetChanged();
}
class
PinTuAdapter
extends
BaseAdapter {
@Override
public
int
getCount() {
return
list.size();
}
@Override
public
Object getItem(
int
position) {
return
null
;
}
@Override
public
long
getItemId(
int
position) {
return
0
;
}
@Override
public
View getView(
int
position, View convertView, ViewGroup parent) {
ViewHolder holder;
if
(convertView ==
null
) {
convertView = View.inflate(MainActivity.
this
, R.layout.item,
null
);
holder =
new
ViewHolder();
holder.iv = (ImageView) convertView.findViewById(R.id.imageView);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
holder.iv.setImageBitmap(list.get(position));
return
convertView;
}
class
ViewHolder {
ImageView iv;
}
}
}
package
myapp.com.day27_2_;
import
android.app.Activity;
import
android.graphics.drawable.AnimationDrawable;
import
android.os.Bundle;
import
android.view.View;
import
android.widget.ImageView;
public
class
MainActivity
extends
Activity {
ImageView iv;
private
AnimationDrawable ad;
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView)findViewById(R.id.imageView);
ad = (AnimationDrawable) iv.getBackground();
// /*
// * 注意: 当该段代码运行的设备比较low,
// * 有可能会造成动画没有运行的效果
// * 原因: 当start方法被调用时,有可能ad中xml文件只读取了一个item的数据
// * 推荐,如果想要让页面一启动就执行帧动画,建议将start方法的调用放到
// * onWindowFocusChanged方法中
// * */
// ad.start();
}
@Override
public
void
onWindowFocusChanged(
boolean
hasFocus) {
super
.onWindowFocusChanged(hasFocus);
ad.start();
}
public
void
click (View v){
switch
(v.getId()) {
case
R.id.button:
ad.start();
// 启动动画
break
;
case
R.id.button2:
ad.stop();
//停止动画
break
;
}
}
}
3_res\drawable\wifi.xml

4》补间动画的实现
package
myapp.com.day27_3_;
import
android.os.Bundle;
import
android.support.v7.app.AppCompatActivity;
import
android.view.View;
import
android.view.animation.Animation;
import
android.view.animation.AnimationUtils;
import
android.view.animation.RotateAnimation;
import
android.widget.ImageView;
public
class
MainActivity
extends
AppCompatActivity {
ImageView iv;
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView)findViewById(R.id.imageView);
}
public
void
click (View v) {
switch
(v.getId()) {
case
R.id.button:
//旋转动画
/*
* 通过loadAnimation方法获取要执行的动画对象
* 1:Context
* 2:要执行的动画文件
* */
// Animation rotate = AnimationUtils.loadAnimation(this, R.anim.rotate_anim);
//
// iv.startAnimation(rotate);
//通过纯代码方式执行旋转动画
Animation rotate =
new
RotateAnimation(
0
,
315
,RotateAnimation.RELATIVE_TO_SELF,
0
.5f,RotateAnimation.RELATIVE_TO_SELF,
0
.5f);
rotate.setDuration(
2000
);
iv.startAnimation(rotate);
break
;
case
R.id.button2:
//平移动画
Animation tran = AnimationUtils.loadAnimation(
this
,R.anim.tran);
iv.startAnimation(tran);
break
;
case
R.id.button3:
Animation duo = AnimationUtils.loadAnimation(
this
,R.anim.duo);
iv.startAnimation(duo);
break
;
}
}
}
3_res\anim\rotate_anim.xml
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
rotate
xmlns:android
=
"http://schemas.android.com/apk/res/android"
android:duration
=
"2000"
android:fromDegrees
=
"0"
android:toDegrees
=
"360"
android:pivotX
=
"50%"
android:pivotY
=
"50%"
android:fillAfter
=
"true"
android:repeatCount
=
"infinite"
android:repeatMode
=
"restart"
android:interpolator
=
"@android:anim/linear_interpolator"
>
<!--
android:duration="2000" 设置旋转动画的执行时间
android:fromDegrees="0" 设置旋转动画的起始角度
android:toDegrees="360" 设置旋转动画的终止角度
以下两条属性用于设置旋转所围绕的中心点的x,y坐标
android:pivotX=""
android:pivotY=""
属性值有3种设置方式:
任意数字 n 屏幕上对应的像素点
n% 相对于自身的位置
n%p 相对于父控件范围的位置
android:fillAfter="true" 设置动画停止在结束状态
android:repeatCount="infinite" 设置重复次数
infinite ,-1 无限次
android:repeatMode="reverse" 重复模式
reverse 重复执行动画时,效果为:从开始状态匀速变为结尾状态,再从结尾状态匀速变为开始状态
restart 每次重复执行动画是都从头开始
-->
</
rotate
>
4_res\anim\tran.xml
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
translate
xmlns:android
=
"http://schemas.android.com/apk/res/android"
android:duration
=
"2000"
android:fromXDelta
=
"0"
android:fromYDelta
=
"0"
android:toXDelta
=
"0"
android:toYDelta
=
"400"
android:interpolator
=
"@android:anim/bounce_interpolator"
>
</
translate
>
<? xml version = "1.0" encoding = "utf-8" ?>
< set xmlns:android = "http://schemas.android.com/apk/res/android" >
< scale
android:duration = "2000"
android:fromXScale = "1"
android:fromYScale = "1"
android:pivotX = "50%"
android:pivotY = "50%"
android:toXScale = "5"
android:toYScale = "5" />
<!--
android:startOffset="4000" 用于指定当前动画在动画开始多长时间之后再执行
-->
< alpha
android:duration = "2000"
android:fromAlpha = "1"
android:startOffset = "4000"
android:toAlpha = "0.3" />
</ set >
|
package
myapp.com.day27_4_;
import
android.animation.Animator;
import
android.animation.AnimatorInflater;
import
android.animation.ObjectAnimator;
import
android.animation.ValueAnimator;
import
android.os.Bundle;
import
android.support.v7.app.AppCompatActivity;
import
android.util.Log;
import
android.view.View;
import
android.widget.ImageView;
import
android.widget.Toast;
public
class
MainActivity
extends
AppCompatActivity {
ImageView iv;
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView)findViewById(R.id.imageView);
iv.setOnClickListener(
new
View.OnClickListener() {
@Override
public
void
onClick(View v) {
Toast.makeText(MainActivity.
this
,
"iv is clicked!!!"
, Toast.LENGTH_SHORT).show();
}
});
}
public
void
click (View v) {
switch
(v.getId()) {
case
R.id.button:
//水平方向的平移
//方式一:通过加载动画xml文件实现
// Animator tranX = AnimatorInflater.loadAnimator(this, R.animator.xtran);
// //设置要执行此动画的控件目标
// tranX.setTarget(iv);
// //启动动画
// tranX.start();
//方式二:通过纯代码实现动画
// /*
// * 1, 要执行此动画的目标控件
// * 2,要执行的动画名称
// * 3, 可变参数,用于设置动画的起始值和结束值
// * */
Animator tranX = ObjectAnimator.ofFloat(iv,
"translationY"
,
0
,
500
);
//设置动画执行的持续时间
tranX.setDuration(
2000
);
tranX.start();;
break
;
case
R.id.button2:
Animator rota = AnimatorInflater.loadAnimator(
this
,R.animator.xrotate);
rota.setTarget(iv);
rota.start();
break
;
case
R.id.button3:
Animator duo = AnimatorInflater.loadAnimator(
this
,R.animator.duo);
duo.setTarget(iv);
duo.start();
//设置属性动画的监听事件
duo.addListener(
new
Animator.AnimatorListener() {
@Override
public
void
onAnimationStart(Animator animation) {
}
@Override
public
void
onAnimationEnd(Animator animation) {
}
@Override
public
void
onAnimationCancel(Animator animation) {
}
@Override
public
void
onAnimationRepeat(Animator animation) {
}
});
break
;
case
R.id.button4:
//自定义动画
ObjectAnimator custom = ObjectAnimator.ofFloat(iv,
"ay"
,
1
,
100
);
custom.setDuration(
2000
);
custom.addUpdateListener(
new
ValueAnimator.AnimatorUpdateListener() {
@Override
public
void
onAnimationUpdate(ValueAnimator animation) {
Log.i(
"==="
,
"==== "
+ animation.getAnimatedValue());
iv.setScaleX((Float) animation.getAnimatedValue() /
10
);
iv.setScaleY((Float) animation.getAnimatedValue());
// iv.setTranslationZ((Float) animation.getAnimatedValue());
iv.setRotationY((Float) animation.getAnimatedValue());
}
});
custom.start();
break
;
}
}
}
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
objectAnimator
xmlns:android
=
"http://schemas.android.com/apk/res/android"
android:duration
=
"2000"
android:propertyName
=
"rotationX"
android:valueFrom
=
"0"
android:valueTo
=
"315"
android:valueType
=
"floatType"
>
<!--
android:propertyName="translationX" 用于设置当前要执行的动画的名称
android:valueType 用于指定稍后设置动画起始值和终止值时,数据的类型
android:valueFrom="" 动画起始状态
android:valueTo="" 动画结束状态
-->
</
objectAnimator
>
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
<
set
xmlns:android
=
"http://schemas.android.com/apk/res/android"
android:ordering
=
"sequentially"
>
<
objectAnimator
android:duration
=
"2000"
android:propertyName
=
"rotationY"
android:valueType
=
"floatType"
android:valueTo
=
"360"
android:valueFrom
=
"0"
/>
<
objectAnimator
android:duration
=
"2000"
android:propertyName
=
"scaleX"
android:valueType
=
"floatType"
android:valueTo
=
"1"
android:valueFrom
=
"3"
/>
<
objectAnimator
android:duration
=
"2000"
android:propertyName
=
"alpha"
android:valueType
=
"floatType"
android:valueTo
=
"0.3"
android:valueFrom
=
"1"
/>
</
set
>