Android custom View implements Address Book letter index (similar to WeChat Address Book) and android address book

Source: Internet
Author: User

Android custom View implements Address Book letter index (like Address Book) and android address book

I. effect: we can see that many software address books have a letter index function on the right, such as Xiaomi Address Book, QQ, and Meituan selection areas. Here I have taken a picture of the selected city of Meituan;

Today, we will implement the index function of the module on the right of the image, including touch display to select the index letters. Here, my UI is mainly implemented by reference to the interface, so you can also compare it to see the effect, nothing to say, only the most convincing!

Ii. Analysis:
We can see this effect, and we will all go back and figure out how he achieves it;
First, it must be implemented through custom View, because Android does not provide such controls, then the next step is how to customize our View, we know that the two most important methods for customizing a View are onDraw (Canvas canvas) and
OnMeasure (int widthMeasureSpec, int heightMeasureSpec) method. Of course, if it is a custom ViewGroup, it must be implemented.
OnLayout (boolean changed, int left, int top, int right, int bottom) method. here we can use custom View to implement this function, when you touch this area, a Toast-like floating box will pop up to display the selected index content. Therefore, you need to overwrite the onTouchEvent (MotionEvent event) event of the View, finally, it is the implementation of the floating box. Then we will start encoding.

Iii. coding implementation:
We will implement it in the order of View execution.
1. Implement the onMeasure (int widthMeasureSpec, int heightMeasureSpec) method. The function of this method is to measure our width and height. For specific implementation, see the code.

    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        setMeasuredDimension(measureWidth(widthMeasureSpec),measureHeight(heightMeasureSpec));    }

The following two methods are defined: measureWidth (int) and measureHeight (int). You can use the method name to clearly understand that the function is to measure the width and height respectively. Let's see how the measurement is made.

/*** The size of the measurement. Here, only the measurement width * @ param widthMeaSpec refers to the measurement standard of the parent View * @ return the width of the measurement */private int measureWidth (int widthMeaSpec) {/* define the width of the view */int width;/* obtain the Measurement mode of the current View */int mode = MeasureSpec. getMode (widthMeaSpec);/** get the measured value of the current View. Only the initial value is obtained here, * we also need to determine the expected size based on the Measurement Mode **/int size = MeasureSpec. getSize (widthMeaSpec);/** if the mode is exact mode * the width of the current View is our * size; **/if (mode = MeasureSpec. EXACTLY) {width = size;} else {/* otherwise, we need to combine the padding value to determine */int desire = size + getPaddingLeft () + getPaddingRight (); if (mode = MeasureSpec. AT_MOST) {width = Math. min (desire, size) ;}else {width = desire ;}} mViewWidth = width; return width ;}

The above is the code for measuring the width. The code for measuring the height is roughly the same as the code for measuring the width. I will not post it. I will add the source code at the end.

2. Implement the onDraw (Canvas c) method. This method is very familiar to everyone, that is, to draw the content of these indexes to the View, including the background color changes during the selection;

    @Override    protected void onDraw(Canvas canvas) {        if(mTouched){            canvas.drawColor(0x30000000);        }        for (int i = 0 ; i < mIndex.length ; i ++){            mPaint.setColor(0xff000000);            mPaint.setTextSize(mTextSize * 3.0f / 4.0f);            mPaint.setTypeface(Typeface.DEFAULT) ;            mPaint.getTextBounds(mIndex[i],0,mIndex[i].length(),mTextBound);            float formX = mViewWidth/2.0f - mTextBound.width()/2.0f ;            float formY = mTextSize*i + mTextSize/2.0f + mTextBound.height()/2.0f ;            canvas.drawText(mIndex[i],formX,formY,mPaint);            mPaint.reset();        }    }

Let me talk about what is done in the onDraw method. First, draw the background color. Note that it will not be drawn as soon as it comes up, but the background color will be drawn when there is a finger touch. Second, it is the content of the index. The size and position of the content should be determined based on the width and height of the current View.

3. Implementation of the onTouchEvent (MotionEvent) Method

@ Override public boolean onTouchEvent (MotionEvent event) {float y = event. getY (); int index = (int) (y/mTextSize); if (index> = 0 & index <mIndex. length) {Log. v ("zgy", "===== index ======" + index); selectItem (index) ;}if (event. getAction () = MotionEvent. ACTION_MOVE) {mTouched = true;} else if (event. getAction () = MotionEvent. ACTION_MOVE) {} else {mFloatView. setVisibility (INVISIBLE); mTouched = false;} invalidate ();/* filter other touch events */return true ;}

The code is relatively simple. First, obtain the point of the current touch and obtain the index position based on the coordinate of the point.

4. Here we have actually achieved the desired effect, but we still cannot use it. here we need to define a callback interface.

/* Define a callback interface */public interface OnIndexSelectListener {/* return the selected position and corresponding index name */void onItemSelect (int position, String value );}

Where can we call the callback interface? When we press the finger, we need to determine which index we press, and the same is true when we slide, there is nothing to discuss about. You can directly put it in onTouchEvent (MotionEvent,

        float y = event.getY() ;        int index = (int) (y / mTextSize);        if(index >= 0 && index < mIndex.length){            Log.v("zgy","======index======="+index) ;            selectItem(index);        }

The selectItem (int) method is the callback method executed.
5. Implement the floating box to display the selected index content
The WindowManager container is used here. However, you only need to attach the actual View to this container. When you press your finger, display the View and release it.

/* Set the floating Index * // * obtain windowManager */mWindowManager = (WindowManager) getContext (). getSystemService (Context. WINDOW_SERVICE);/* overly view, obtained through LayoutInflater */mFloatView = LayoutInflater. from (getContext ()). inflate (R. layout. overlay_indexview, null);/* starts to make it invisible */mFloatView. setVisibility (INVISIBLE);/* The conversion height and width are Sp */mOverlyWidth = (int) TypedValue. applyDimension (TypedValue. COMPLEX_UNIT_DIP, 70, getResources (). getDisplayMetrics (); mOverlyHeight = (int) TypedValue. applyDimension (TypedValue. COMPLEX_UNIT_DIP, 70, getResources (). getDisplayMetrics (); post (new Runnable () {@ Override public void run () {WindowManager. layoutParams layoutParams = new WindowManager. layoutParams (mOverlyWidth, mOverlyHeight, WindowManager. layoutParams. TYPE_APPLICATION, WindowManager. layoutParams. FLAG_NOT_TOUCHABLE | WindowManager. layoutParams. FLAG_NOT_FOCUSABLE, PixelFormat. TRANSLUCENT); mWindowManager. addView (mFloatView, layoutParams );}});

Similarly, if you need to change the displayed content, you need to set the current index content for TextView in the View at the position where the callback is called.
Now there are so many code for this View,
Next, we will post the Xml that references the object and the floating View,

Referenced layout File

    <moon.wechat.view.IndexView        android:layout_width="25dp"        android:layout_height="match_parent"        android:layout_alignParentRight="true"/>

Layout file of floating View

<?xml version="1.0" encoding="utf-8"?><TextView xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/overly_text"    android:layout_width="70dp"    android:layout_height="70dp"    android:text="A"    android:gravity="center"    android:background="@drawable/bg_overly_text"    android:textSize="40sp"    android:textColor="#ffffffff"    android:layout_gravity="center"></TextView>

Floating View background

<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android">    <item>        <shape>            <solid android:color="#88000000"/>            <corners android:radius="5dp"/>        </shape>    </item></layer-list>

Source code: here

Related Article

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.