A few simple steps show you how to cut and display the slice area of Drawable.

Source: Internet
Author: User

A few simple steps show you how to cut and display the slice area of Drawable.

If you like my blog, please pay attention to my Weibo, please click here (http://weibo.com/kifile), thank you

Reprinted please indicate the source (http://blog.csdn.net/kifile), thank you again


In the development process, the simple Drawable file cannot meet our requirements for the entire project.

Sometimes we want to display a Drawable file in a clockwise manner when making an animation. However, Android does not provide a tool class for us, we do not want to create N images to simply display the entire image to meet the needs of the scene animation. At this time, we can only consider cropping the Drawable painting area, let him show only the size of the slice area to meet our needs.

Fortunately, Android itself has a ClipDrawable class, which allows us to easily display the progress bar loading progress. This time we will also create a similar code based on this class.

First, the specific source code is provided, and then the principle of cropping the display area is analyzed in detail.

/** Copyright (C) 2014 Kifile (kifile@kifile.com) ** Licensed under the Apache License, Version 2.0 (the "License "); * you may not use this file before t in compliance with the License. * You may obtain a copy of the License at ** http://www.apache.org/licenses/LICENSE-2.0 ** Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an" S is "BASIS, * without warranties or conditions of any kind, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com. kifile. graphics; import android. content. res. colorStateList; import android. graphics. *; import android. graphics. drawable. drawable;/*** Created by kifile on 14/10/31. */public class SectorDrawable ex Tends Drawable implements Drawable. callback {private Drawable mDrawable; private Path mPath = new Path (); private float mPercent; public SectorDrawable (Drawable drawable) {this. mDrawable = drawable; if (drawable! = Null) {drawable. setCallback (this) ;}@override public int getChangingConfigurations () {return super. getChangingConfigurations () | mDrawable. getChangingConfigurations () ;}@ Override public boolean getPadding (Rect padding) {return mDrawable. getPadding (padding) ;}@ Override public boolean setVisible (boolean visible, boolean restart) {mDrawable. setVisible (visible, restart); return super. setVisi Ble (visible, restart) ;}@ Override public void draw (Canvas canvas) {mPath. reset (); RectF rect = new RectF (getBounds (); double radius = Math. pow (Math. pow (rect. right, 2) + Math. pow (rect. bottom, 2), 0.5); mPath. moveTo (rect. right/2, rect. bottom/2); mPath. lineTo (rect. right/2, 0); if (mPercent> 0.125f) {mPath. lineTo (rect. right, 0);} if (mPercent> 0.375f) {mPath. lineTo (rect. right, rect. botto M);} if (mPercent> 0.625f) {mPath. lineTo (0, rect. bottom);} if (mPercent> 0.875f) {mPath. lineTo (0, 0);} mPath. lineTo (float) (rect. right/2 + radius * Math. sin (Math. PI * 2 * mPercent), (float) (rect. bottom/2-radius * Math. cos (Math. PI * 2 * mPercent); mPath. close (); if (mPercent> = 0 & mPercent <= 1) {canvas. save (); canvas. clipPath (mPath); mDrawable. draw (canvas); canvas. restore ();}} @ Override public void setAlpha (int alpha) {mDrawable. setAlpha (alpha) ;}@ Override public int getAlpha () {return mDrawable. getAlpha () ;}@ Override public void setColorFilter (ColorFilter cf) {mDrawable. setColorFilter (cf) ;}@ Override public void setTintList (ColorStateList tint) {mDrawable. setTintList (tint) ;}@ Override public void setTintMode (PorterDuff. mode tintMode) {mDrawable. setTintMode (TintMode) ;}@ Override public int getOpacity () {// TODO Auto-generated method stub return mDrawable. getOpacity () ;}@ Override public boolean isStateful () {// TODO Auto-generated method stub return mDrawable. isStateful () ;}@ Override protected boolean onStateChange (int [] state) {return mDrawable. setState (state) ;}@ Override protected boolean onLevelChange (int level) {mDrawable. setLevel (level ); InvalidateSelf (); return true;} @ Override protected void onBoundsChange (Rect bounds) {mDrawable. setBounds (bounds) ;}@ Override public int getIntrinsicHeight () {return mDrawable. getIntrinsicHeight () ;}@ Override public int getIntrinsicWidth () {return mDrawable. getIntrinsicWidth ();}/** display area range ** @ param percent 0 to 1 */public void setPercent (float percent) {if (percent> 1) {percent = 1 ;} Else if (percent <0) {percent = 0;} if (percent! = MPercent) {this. mPercent = percent; invalidateSelf () ;}}@ Override public void invalidateDrawable (Drawable who) {final Callback callback = getCallback (); if (callback! = Null) {callback. invalidateDrawable (this) ;}@ Override public void scheduleDrawable (Drawable who, Runnable what, long when) {final Callback callback = getCallback (); if (callback! = Null) {callback. scheduleDrawable (this, what, when) ;}@ Override public void unscheduleDrawable (Drawable who, Runnable what) {final Callback callback = getCallback (); if (callback! = Null) {callback. unscheduleDrawable (this, what );}}}

From the code above, we can see that we use the modifier mode to process this class. First, we pass in an actual Drawable object in the constructor, various transactions are handed over to the Drawable object for processing. We are only responsible for rewriting the draw method, so we can take a good look at the draw method.

First, let's take a look at the figure:


The black part is the canvas area, w is the width, h is the height, radius is the distance from the center to the angle, and nine important coordinate points are marked for us, next we will introduce how to set the range of the selected region based on the rotation angle.

First, we first specify the starting position of the slice area as (w/), and the rotation method is clockwise. Assume that A point is the other side of the slice area, the length is radius (see the preceding section for the definition of radius ).

(1) When the rotation area cannot exceed 1/8, the slice area is drawn as follows:


We can see from the figure that the area we need to cut is the blue area in the middle.

(2) If the rotation area exceeds 1/8 and does not exceed 3/8, the slice area is drawn as follows:


We can see from the figure that the blue area we need to cut consists of A central point, A starting point, and A link to A in the upper right corner.

(3) When the rotation area exceeds 3/8 and does not exceed 5/8, the slice area is drawn as follows:


We can see from the figure that the blue area we need to cut consists of the central point, starting point, top right corner, bottom right corner and A point.

(4) For parts exceeding 5/8 and not exceeding 7/8, the cropping area is as follows:


(5) For parts exceeding 7/8, the cut-off areas are as follows:



Therefore, we can dynamically cut the canvas by judging the set display area to display the slice area.


The specific setting code is on the top. If you are interested, you can take a look at it in detail. Next we will see how to correctly use SectorDrawable

ImageView img = (ImageView) findViewById(R.id.sector_img);        mDrawable = new SectorDrawable(img.getDrawable());        img.setImageDrawable(mDrawable);
In this Code, we get a Drawable object from ImageView, then use SectorDrawable to decorate it, and then set setctorDrawable to ImageView.

Use

mDrawable.setPercent(percent);

A detailed example of an Activity is as follows:
/* * Copyright (C) 2014 Kifile(kifile@kifile.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *    http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.kifile.sample.app;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.support.v7.app.ActionBarActivity;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import android.widget.ImageView;import com.kifile.graphics.SectorDrawable;public class MainActivity extends ActionBarActivity {    private SectorDrawable mDrawable;    private Handler mHandler = new Handler() {        private float percent;        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            if (percent <= 1) {                percent += 0.01;            } else {                percent = 0;                return;            }            mDrawable.setPercent(percent);            Log.i("this",String.valueOf(percent));            sendEmptyMessageDelayed(0, 10);        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        ImageView img = (ImageView) findViewById(R.id.sector_img);        mDrawable = new SectorDrawable(img.getDrawable());        img.setImageDrawable(mDrawable);    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        // Inflate the menu; this adds items to the action bar if it is present.        getMenuInflater().inflate(R.menu.menu_main, menu);        return true;    }    @Override    public boolean onOptionsItemSelected(MenuItem item) {        // Handle action bar item clicks here. The action bar will        // automatically handle clicks on the Home/Up button, so long        // as you specify a parent activity in AndroidManifest.xml.        int id = item.getItemId();        //noinspection SimplifiableIfStatement        if (id == R.id.action_settings) {            mHandler.sendEmptyMessage(0);            return true;        }        return super.onOptionsItemSelected(item);    }}

This code will trigger an event when you click the menu button, and use handler to constantly refresh the display area to display the slice area.


Now, this blog is here. Thank you for reading it.





Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.