Android 高级图形图像处理

文章目录

    • 1. 绘制矩形、扇形、圆角矩形
    • 2.用xml代码布局文件实现复杂的图像
    • 3.圆环形渐变
    • 4.矩形渐变
    • 5.渐变线
    • 6.动态渐变
    • 7.对图片进行裁剪
    • 8.灵活的调用图片在Imageview显示
    • 9.红色小圆球样式的新消息提醒
    • 10.线性梯度渐变渲染(LinearGradient)
    • 11.扫描梯度渐变渲染器(SweepGradient)
    • 12.放射环状梯度渐变渲染器(RadialGradient)
    • 13.用shape文件实现线性梯度渐变渲染
    • 14.用shape文件实现放射状梯度渐变渲染
    • 15.用shape文件实现扫描形梯度渐变渲染
    • 16.透明渐变属性动画
    • 17.旋转属性动画
    • 18.位移属性动画
    • 19.拉申属性动画
    • 20.酷炫的动画往往不止一个效果,而是同时,或是按照一定序列联合执行一组动画集。AnimatorSet(动画集)
    • 21.拖曳管控
    • 22.横竖屏切换不同尺寸的view
    • 23.onMeasure控制view的尺寸大小
    • 24.onLayout控制子View的空间位置
    • 25.Android手机在状态栏的消息通知

1. 绘制矩形、扇形、圆角矩形

// activity_main.xml

    
    
    
    


//main.java
 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //圆角矩形
        //PaintDrawable继承自ShapeDrawable
        PaintDrawable drawable1=new PaintDrawable(Color.GREEN);
        drawable1.setCornerRadius(60);//圆角弧度
        findViewById(R.id.textview1).setBackgroundDrawable(drawable1);

        //椭圆
        OvalShape ovalShape = new OvalShape();
        ShapeDrawable drawable2=new ShapeDrawable(ovalShape);
        drawable2.getPaint().setColor(Color.BLUE);
        drawable2.getPaint().setStyle(Paint.Style.FILL);//填充形式为完全填充
        findViewById(R.id.textview2).setBackgroundDrawable(drawable2);

        //矩形
        RectShape rectShape =new RectShape();
        ShapeDrawable drawable3=new ShapeDrawable(rectShape);
        drawable3.getPaint().setColor(Color.RED);
        drawable3.getPaint().setStyle(Paint.Style.FILL);//填充形式为完全填充
        findViewById(R.id.textview3).setBackgroundDrawable(drawable3);

        //弧度扇形
        ArcShape arcShape = new ArcShape(100,120);//顺时针开始角度100°, 绘制区域为120°
        ShapeDrawable drawable4=new ShapeDrawable(arcShape);
        drawable4.getPaint().setColor(Color.BLACK);
        drawable4.getPaint().setStyle(Paint.Style.FILL);//填充形式为完全填充
        findViewById(R.id.textview4).setBackgroundDrawable(drawable4);

    }

2.用xml代码布局文件实现复杂的图像

IDE: Android studio
【1】创建Shape文件:
	(1)	右击app->New->Android resource file
	(2)	File name: 填写Shape文件的名字(如 gradient)
	(3)	Resource type: Drawable
	(4)	Root element: shape
	(5)	Shape文件中的代码如下:

 // 定义一个椭圆

    

    



【2】在布局文件activity_main.xml中加入


    



【3】java代码中只需
setContentView(R.layout.activity_main);


3.圆环形渐变

shape文件代码如下(替换实例2的shap文件)




    

    




4.矩形渐变

shape文件如下(替换实例2的shap文件)




    

    



5.渐变线

shape文件如下(替换实例2的shap文件)




    

    



6.动态渐变

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

        Drawable[] drawables=new Drawable[]{new ColorDrawable(Color.TRANSPARENT),new ColorDrawable(Color.RED)};

        TransitionDrawable mTransitionDrawable=new TransitionDrawable(drawables);

        ImageView image=(ImageView)findViewById(R.id.image_view);
        image.setImageDrawable(mTransitionDrawable);

        mTransitionDrawable.setCrossFadeEnabled(true);
        mTransitionDrawable.startTransition(10000);
        
    }

7.对图片进行裁剪

#正常图像
        ImageView image1=(ImageView) findViewById(R.id.image_view1);
        image1.setImageResource(R.drawable.yes);

#矩形四角磨成圆脚
        RoundedBitmapDrawable round= RoundedBitmapDrawableFactory.create(getResources()
        , BitmapFactory.decodeResource(getResources(),R.drawable.yes));
        round.getPaint().setAntiAlias(true);
        round.setCornerRadius(30);
        ImageView image2=(ImageView) findViewById(R.id.image_view2);
        image2.setImageDrawable(round);

#裁剪为圆形图像
        Bitmap bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.yes);
        RoundedBitmapDrawable circle= RoundedBitmapDrawableFactory.create(getResources()
                , BitmapFactory.decodeResource(getResources(),R.drawable.yes));
        circle.getPaint().setAntiAlias(true);
        circle.setCornerRadius(Math.max(bitmap.getWidth(),bitmap.getHeight()));
        ImageView image3=(ImageView) findViewById(R.id.image_view3);
        image3.setImageDrawable(circle);

8.灵活的调用图片在Imageview显示

p.xml(在drawable中)代码如下:



    
    
    


*.java

        ImageView image1=(ImageView) findViewById(R.id.image_view1);
        image1.setImageResource(R.drawable.p);
        image1.setImageLevel(3);

9.红色小圆球样式的新消息提醒

*.java

setContentView(R.layout.activity_main);

shape文件(round.xml)



    
    
    
    
    
    

shape文件(tips_circle.xml)



    


布局文件





    
    

    
    



Android常见的渲染器有三种:LinearGradient、SweepGradient、RadialGradient

10.线性梯度渐变渲染(LinearGradient)

//activity_main.xml


 


重写view中的ondraw,LinearGradientVIew .java

public class LinearGradientVIew extends View {
//
    LinearGradient linearGrandient1,linearGrandient2,linearGrandient3,linearGrandient4,linearGrandient5;
    Paint paint1,paint2,paint3,paint4,paint5;

    public LinearGradientVIew(Context context) {
        super(context);
        linearGrandient1=new LinearGradient(0,0,300,0,new int[]{Color.RED,Color.YELLOW,Color.BLUE},null, Shader.TileMode.REPEAT);
        paint1=new Paint();

        linearGrandient2=new LinearGradient(0,0,300,0,new int[]{Color.RED,Color.YELLOW,Color.BLUE},null, Shader.TileMode.MIRROR);
        paint2=new Paint();

        linearGrandient3=new LinearGradient(0,0,300,0,new int[]{Color.RED,Color.YELLOW,Color.BLUE},null, Shader.TileMode.CLAMP);
        paint3=new Paint();

        //绘制起点(0,0),绘制终点(100,100)。然后已此图形进行对称渲染,渲染样式为CLAMP(拉伸模式)、MIRROR(平面镜)、REPEAT(重复渲染)
        linearGrandient4=new LinearGradient(0,0,100,100,new int[]{Color.RED,Color.YELLOW,Color.BLUE},null, Shader.TileMode.REPEAT);
        paint4=new Paint();

        linearGrandient5=new LinearGradient(0,300,300,0,new int[]{Color.RED,Color.YELLOW,Color.BLUE},null, Shader.TileMode.REPEAT);
        paint5=new Paint();

    }

    //onDraw()方法负责绘制,即如果我们希望得到的效果在Android原生控件中没有现成的支持,
    // 那么我们就需要自己绘制我们的自定义控件的显示效果。
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int left=10,top=20,right=0,bottom=0;
        right=this.getWidth()-left;

        bottom=this.getHeight()/5;

        paint1.setShader(linearGrandient1);
        Rect rect1=new Rect(left,top,right,bottom);
        canvas.drawRect(rect1,paint1);

        top=top+bottom;

        paint2.setShader(linearGrandient2);
        Rect rect2=new Rect(left,top,right,bottom*2);
        canvas.drawRect(rect2,paint2);

        top=top+bottom;

        paint3.setShader(linearGrandient3);
        Rect rect3=new Rect(left,top,right,bottom*3);
        canvas.drawRect(rect3,paint3);

        top=top+bottom;

        paint4.setShader(linearGrandient4);
        Rect rect4=new Rect(left,top,right,bottom*4);
        canvas.drawRect(rect4,paint4);

        top=top+bottom;

        paint5.setShader(linearGrandient5);
        Rect rect5=new Rect(left,top,right,bottom*5);
        canvas.drawRect(rect5,paint5);
    }

}

main_activity.java

public class MainActivity extends Activity {

    LinearGradientVIew view1;

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

            view1=new LinearGradientVIew(getApplicationContext());
            LinearLayout lin=(LinearLayout)findViewById(R.id.li);
            lin.addView(view1);

        }
}

11.扫描梯度渐变渲染器(SweepGradient)

activity_main.xml



    
	
    


SweepGradientView .java

public class SweepGradientView extends View {
    SweepGradient mSweepGradient;
    Paint mPaint;
    Canvas canvas;

    ////在MainActivity.java文件中调用自己写的view时调用该构造方法
    public SweepGradientView(Context context) {
        super(context);
    }

    //在xml布局文件中调用自己写的view时调用改构造方法
    public SweepGradientView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

        @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        mSweepGradient=new SweepGradient(this.getWidth()/2,this.getHeight()/2,
                new int[]{Color.TRANSPARENT,Color.RED,Color.TRANSPARENT,Color.
                        YELLOW,Color.BLUE},null);

        mPaint=new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setShader(mSweepGradient);
        canvas.drawCircle(this.getWidth()/2,this.getHeight()/2,300,mPaint);
    }

    //Android通过onMeasure()测量View的大小,默认情况下是EXACTLY模式
    //EXACTLY 精确模式 例如layout_height=”50dp”或是=”match_parent”
    //AT_MOST 最大值模式 就是warp_content
    //UNSPECIFIED 通过字面意思就是没有指定尺寸
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //先声明两个int值来表示最终的width和height并给定一个默认的大小
        int width_size  = 100;
        int height_size = 100;

        //使用MeasureSpec分别获取width和height的MODE和SIZE
        int HEIGHT_MODE = MeasureSpec.getMode(heightMeasureSpec);
        int HEIGHT_SIZE = MeasureSpec.getSize(heightMeasureSpec);
        int WIDTH_MODE = MeasureSpec.getMode(widthMeasureSpec);
        int WIDTH_SIZE = MeasureSpec.getSize(widthMeasureSpec);
        if (HEIGHT_MODE == MeasureSpec.EXACTLY) {
            height_size = HEIGHT_SIZE;       //如果测量模式是精确的话 那么就直接使用获取到的值就好了
        }else if (HEIGHT_MODE == MeasureSpec.AT_MOST){  //如果是最大值模式的话 那么久比较获取的和设定的默认值那个小就使用那个.ps:Math.min(int a,int b)是比较数值大小的.
            height_size = Math.min(HEIGHT_SIZE,height_size);
        }
        if (WIDTH_MODE == MeasureSpec.EXACTLY){
            width_size = WIDTH_SIZE;
        }else if (WIDTH_MODE == MeasureSpec.AT_MOST){
            width_size = Math.min(WIDTH_SIZE,width_size);
        }

        //测量完毕后得到的了width和height通过setMeasuredDimension()设置width和height,真正决定具体大小的是setMeasuredDimension()的两个参数.
        setMeasuredDimension(width_size,height_size);
    }
}

MainActivity.java

public class MainActivity extends Activity {

    SweepGradientView view1;

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

12.放射环状梯度渐变渲染器(RadialGradient)

RadialGradientView .java

public class RadialGradientView extends View {

    private float radius =480;
    private RadialGradient mRadialGradient;
    private Paint mPaint;

    public RadialGradientView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mRadialGradient=new RadialGradient(this.getWidth()/2,this.getHeight()/2,
                radius,new int[]{Color.RED,Color.TRANSPARENT,Color.BLACK},null,
                Shader.TileMode.CLAMP);
                
        mPaint=new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setShader(mRadialGradient);
        canvas.drawCircle(this.getWidth()/2,this.getHeight()/2,radius,mPaint);
    }
}

MainActivity.java与例子11相同。只需将例11中activity_main.xml里的包名.类名改为包名.RadialGradientView 。


13.用shape文件实现线性梯度渐变渲染

gradient.xml



    
    

MainActivity.java和activity_main.xml与例子2中的一样


14.用shape文件实现放射状梯度渐变渲染



    
    

MainActivity.java和activity_main.xml与例子2中的一样


15.用shape文件实现扫描形梯度渐变渲染



    
    

MainActivity.java和activity_main.xml与例子2中的一样


16.透明渐变属性动画

public class MainActivity extends Activity {

    TextView mTextView;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mTextView= (TextView) findViewById(R.id.li);
            startPropertyAnim();//动画的执行要在主线程中执行
        }

    private void startPropertyAnim(){
        //1->0.1->1->0.5->1(完全不透明)
        ObjectAnimator mObjectAnimator = ObjectAnimator.ofFloat(mTextView,"alpha",1f,0.1f,1f,0.5f,1f);

        mObjectAnimator.setDuration(5000);//动画持续时间

        //这是一个回掉监听,获取属性动画在执行期间的具体值
        /*mObjectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value= (float) animation.getAnimatedValue();
                //Log.d("动画的值",value+"");

            }
        });*/
        mObjectAnimator.start();
    }
}

17.旋转属性动画

public class MainActivity extends Activity {

    TextView mTextView;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mTextView= (TextView) findViewById(R.id.li);
            startPropertyAnim();//动画的执行要在主线程中执行
        }

    private void startPropertyAnim(){
        //rotation(旋转动画),0f~360f为mTextView顺时针旋转360度
        ObjectAnimator mObjectAnimator = ObjectAnimator.ofFloat(mTextView,"rotation",0f,360f);

        mObjectAnimator.setDuration(5000);//动画持续时间

        //这是一个回掉监听,获取属性动画在执行期间的具体值
        /*mObjectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value= (float) animation.getAnimatedValue();
                //Log.d("动画的值",value+"");

            }
        });*/
        mObjectAnimator.start();
    }
}

18.位移属性动画

public class MainActivity extends Activity implements View.OnClickListener{

    TextView mTextView;
    ObjectAnimator mObjectAnimator;
    Button but;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mTextView= (TextView) findViewById(R.id.li);
            startPropertyAnim();//动画的执行要在主线程中执行

            but= (Button) findViewById(R.id.button);
            but.setOnClickListener(this);
        }

    private void startPropertyAnim(){
        float translationX=mTextView.getTranslationX();
        //translationX(水平位移)、translationY(垂直位移);
        //ofFloat(,,开始位置,中间位置,结束位置)
        mObjectAnimator = ObjectAnimator.ofFloat(mTextView,"translationX",translationX,500f,translationX);

        mObjectAnimator.setDuration(5000);//动画持续时间
        
        //mObjectAnimator.start();
    }

    @Override
    public void onClick(View v) {
        mObjectAnimator.start();
    }
}



    

    

19.拉申属性动画

替换例18中的startPropertyAnim就可。

    private void startPropertyAnim(){

        //ofFloat(,,开始拉申长度,中间拉申长度,结束拉申长度)
        mObjectAnimator = ObjectAnimator.ofFloat(mTextView,"scaleX",1f,5f,5f);

        mObjectAnimator.setDuration(5000);//动画持续时间

        //mObjectAnimator.start();
    }

20.酷炫的动画往往不止一个效果,而是同时,或是按照一定序列联合执行一组动画集。AnimatorSet(动画集)

public class MainActivity extends Activity implements View.OnClickListener{

    TextView mTextView;
    ObjectAnimator alpha,rotation,translationX,scaley;
    Button but;
    AnimatorSet mAnimatorset;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mTextView= (TextView) findViewById(R.id.li);
            startPropertyAnim();//动画的执行要在主线程中执行

            but= (Button) findViewById(R.id.button);
            but.setOnClickListener(this);
        }

    private void startPropertyAnim(){
        //透明渐变
        alpha = ObjectAnimator.ofFloat(mTextView,"alpha",1f,0f,1f);
        //旋转
        rotation= ObjectAnimator.ofFloat(mTextView,"rotation",0f,360f);
        //位移
        float translationx=mTextView.getTranslationX();
        translationX=ObjectAnimator.ofFloat(mTextView,"translationX",translationx,200f,translationx);
        //缩放
        scaley= ObjectAnimator.ofFloat(mTextView,"scaleY",1f,5f,1f);

        mAnimatorset=new AnimatorSet();
        mAnimatorset.setDuration(1000);//动画持续时间

        mAnimatorset.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                //动画结束
            }

            @Override
            public void onAnimationStart(Animator animation) {
                super.onAnimationStart(animation);
                //动画开始
            }
        });
        /*
        play()
        with(a) a与现有动画同时执行
        before(a) a在现有动画之后执行
        after(a) a在现有动画之前执行
         */
        //先执行after(),再次同时执行play()和with(),其次执行before()
        mAnimatorset.play(alpha).with(rotation).before(scaley).after(translationX);
    }

    @Override
    public void onClick(View v) {
        mAnimatorset.start();
    }
}

布局文件在例18


21.拖曳管控

1.实现三个TextView的拖曳
// myActivity.java

public class myActivity extends Activity {

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

// MyLayout.java

public class MyLayout extends LinearLayout {

    private ViewDragHelper mViewDragHelper;

    public MyLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        mViewDragHelper=ViewDragHelper.create(this,1.0f,new ViewDragHelperCallback());
    }

    //回调函数
    private class ViewDragHelperCallback extends ViewDragHelper.Callback{

        @Override
        public boolean tryCaptureView(View child, int pointerId) {
            ///return false;
            return true; //view允许被托曳移动
        }

        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {
            //return super.clampViewPositionHorizontal(child, left, dx);
            return left;
        }

        @Override
        public int clampViewPositionVertical(View child, int top, int dy) {
            //return super.clampViewPositionVertical(child, top, dy);
            return top;
        }

        @Override
        public void onViewDragStateChanged(int state) {
            super.onViewDragStateChanged(state);
        }
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        //return super.onInterceptTouchEvent(ev);
        return mViewDragHelper.shouldInterceptTouchEvent(ev);
    }

    //分析处有效的屏幕滑动事件
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //return super.onTouchEvent(event);
        mViewDragHelper.processTouchEvent(event);
        return true;
    }
}

// activity_my_layout.xml




    

    

    


2.实现三个TextView的拖曳让其不能越界

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_layout);
    }
public class MyLayout extends LinearLayout {

    private ViewDragHelper mViewDragHelper;

    public MyLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        mViewDragHelper=ViewDragHelper.create(this,1.0f,new ViewDragHelperCallback());
    }

    //回调函数
    private class ViewDragHelperCallback extends ViewDragHelper.Callback{

        @Override
        public boolean tryCaptureView(View child, int pointerId) {

            //红色view不允许被托曳移动
            if(child.getId()==R.id.red)
                return false;

            return true; //view允许被托曳移动
        }

        //控制水平方向的view位置.left为该view左边水平坐标.
        @Override
        public int clampViewPositionHorizontal(View child, int left, int dx) {
            //return super.clampViewPositionHorizontal(child, left, dx);

            //getPaddingLeft()为距父view的左边宽度(是一个固定值,由父view设定.可认为子view的左起点宽度)
            if(getPaddingLeft()>left) //让子view不能往左边越界
                return getPaddingLeft();

            //getWidth()为父view的宽度
            //getPaddingLeft()为距父view的右边宽度(是一个固定值,由父view设定.可认为子view的右起点宽度)
            if(getWidth()-child.getWidth()-getPaddingRight()


    

    

    

    



22.横竖屏切换不同尺寸的view

(本节采用的是两套不同屏幕方向的xml布局文件资源,可灵活配置和快捷开发。降低后期对java代码的维护。)
Android layout属性大全:

https://www.jianshu.com/p/62237e236d0b

如何在Android Studio创建layout_land.xml:

https://blog.csdn.net/lin_dianwei/article/details/64123800

创建后:
在res/layout/activity_main.xml(2)下有两个布局文件分别是activity_main.xml(land)
和activity_main.xml(port)。land(横屏、大屏),port(竖屏、小屏).
注意:以下两个布局文件名都为activity_main.xml。




    
    





    
    


*.java 的Activity中只需加

setContentView(R.layout.activity_main);

23.onMeasure控制view的尺寸大小

onMeasure才是从根本上决定View的尺寸大小的因素,它是view的一个函数。
MyView.java

public class MyView extends View {

    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.setBackgroundColor(Color.RED);
    }

    //onMeasure可分为两个阶段
    //第一阶段:测量阶段
    //第二阶段:赋值阶段
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //测量宽度
        int width=measureWidth(100,widthMeasureSpec);
        //android提供个一些便捷的方式直接计算宽、高值。其实getDefaultSiz()和measureWidth()相似.
        int height = this.getDefaultSize(100,heightMeasureSpec);

        //给自定义view设置具体的宽和高
        setMeasuredDimension(width,height);
    }

    private int measureWidth(int size,int measureSpec){
        //size为初始化值
        int result = size;
        //获取测量模式
        int specMode = MeasureSpec.getMode(measureSpec);
        //该值为Android系统为view测量后默认的宽的值
        int specSize = MeasureSpec.getSize(measureSpec);

        switch (specMode){
            //没有明确定义,不常用
            case MeasureSpec.UNSPECIFIED:
                break;

            //最多,尽可能多,此种模式指父布局为wrap_content
            case MeasureSpec.AT_MOST:
                result=specSize;
                break;

            //精确的完全的,此种模式指父布局为match_content或一个具体值
            case MeasureSpec.EXACTLY:
                result = size;
                break;

        }
        return result;
    }
}

布局文件layout_1.xml




    



Activity只需

public class MainActivity extends Activity {

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

}

24.onLayout控制子View的空间位置

onMeasure()控制View的具体宽、高大小。onLayout()控制View的空间摆放位置。
Android常用的布局,它们的最关键的工作就是摆放View的位置。这一过程的关键既是onLayout()。onLayout在onMeasure之后调用。

public class MyLayout extends ViewGroup {


    public MyLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    //onMeasure主要的作用就是测量ViewGroup的大小(即测量内部子View适合的大小,由此确定ViewGroup(容器)的大小)。
    /*  int widthMeasureSpec, int heightMeasureSpec 。他们是父类传递过来给当前view的一个建议值,
        虽然表面上看起来他们是int类型的数字,其实他们是由mode+size两部分组成的。
        前两位代表mode(测量模式),后面28位才是他们的实际数值(size)。*/
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int measuredWidth = 0;
        int measuredHeight= 0;

        //返回父View下直接子View的个数
        int count=getChildCount();

        for(int i=0;i



    

    

    


Activity只需

setContentView(R.layout.layout_1);

25.Android手机在状态栏的消息通知

----------

参考:http://blog.sina.com.cn/s/blog_7cb2c5d50101c26t.html

android的后台运行在很多service,它们在系统启动时被SystemServer开启,支持系统的正常工作,比如MountService监听是否有SD卡安装及移除,ClipboardService提供剪切板功能,PackageManagerService提供软件包的安装移除及查看等等,应用程序可以通过系统提供的Manager接口来访问这些Service提供的数据。

getSystemService是Android很重要的一个API,它是Activity的一个方法,根据传入的NAME来取得对应的Object,然后转换成相应的服务对象。以下介绍系统相应的服务。

 传入的Name                 |         返回的对象            |        说明
WINDOW_SERVICE                    WindowManager                管理打开的窗口程序

LAYOUT_INFLATER_SERVICE           LayoutInflater               取得xml里定义的view

ACTIVITY_SERVICE                  ActivityManager              管理应用程序的系统状态

POWER_SERVICE                     PowerManger                   电源的服务

ALARM_SERVICE                     AlarmManager                  闹钟的服务

NOTIFICATION_SERVICE              NotificationManager           状态栏的服务

KEYGUARD_SERVICE                  KeyguardManager               键盘锁的服务

LOCATION_SERVICE                  LocationManager               位置的服务,如GPS

SEARCH_SERVICE                    SearchManager                 搜索的服务

VEBRATOR_SERVICE                  Vebrator                      手机震动的服务

CONNECTIVITY_SERVICE              Connectivity                  网络连接的服务

WIFI_SERVICE                      WifiManager                    Wi-Fi服务

TELEPHONY_SERVICE                 TeleponyManager                 电话服务

----------
(1)只实现状态栏上显示通知消息

public class MainActivity extends Activity {

    private final String channelId = "my channel id";
    //通知消息的id,它们把不同的消息通知区分开来。
    private int NOTIFICATION_ID=0xa01;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_1);
        sendNotification();
        /*
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        clearNotification();
        */
    }

    //发送通知消息的函数
    private void sendNotification(){
        //得到NotificationManager对象
        NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

        //对Notification的一些属性进行设置比如:内容,图标,标题,相应notification的动作进行处理等等
        NotificationCompat.Builder mBuilder=new NotificationCompat.Builder(this);
        mBuilder.setSmallIcon(R.mipmap.ic_launcher);
        mBuilder.setContentTitle("标题");
        mBuilder.setContentText("文本");
        
        //Activity跳转代码区标记
        
        Notification notification = mBuilder.build();
        //振动的效果需要增加权限
        notification.defaults = Notification.DEFAULT_SOUND|Notification.DEFAULT_VIBRATE|
                Notification.DEFAULT_LIGHTS;

        //System.currentTimeMillis()为获取当前的毫秒数
        notification.when= System.currentTimeMillis();

        //通过NotificationManager对象的notify()方法来执行一个notification的消息
        notificationManager.notify(NOTIFICATION_ID,notification);
    }

    //清除通知消息的函数
    private void clearNotification(){
        NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        //通过NotificationManager对象的cancel()方法来取消一个notificatioin的消息
        notificationManager.cancel(NOTIFICATION_ID);
    }
}
//振动的效果的权限

(2)状态栏的通知消息点击后启动后台的Activity

将以下代码加到(1)中的//Activity跳转代码区标记位置处

        Intent notificationIntent=new Intent(this,Mac.class);
        int requestCode = 0;
        PendingIntent notificationPendingIntent = PendingIntent.getActivity(this,requestCode,notificationIntent,PendingIntent.FLAG_UPDATE_CURRENT);
        mBuilder.setContentIntent(notificationPendingIntent);

AndroidManifist.xml中加

        
        

你可能感兴趣的:(编程,Android)