Handling custom controls, events

First, the relevant control the API
view.getchildcount () Get the number of child control under the control
view.getchildat () Gets the respective sub-control according to the position
II the control Class
AnimationListener Animation listener interfaces
three custom properties
               Reference website: http: //blog.csdn.net/lmj623565791/article/details/45022631
a custom CustomView (extends View) class
 in the constructor of two parameters, acquired attribute ID, and converts it to BitMap object, onDraw (Canvas canvas ) the method of canvas
 which was painted on the panel, which involves the custom properties:
 there are two ways: AttributeSet and TypedArray
      first: by acquiring type int TypedArray ID
public MyTextView the context context (, AttributeSet attrs) {
Super (context, attrs); the TypedArray TA = context.obtainStyledAttributes (attrs, R.styleable.test); String text = ta.getString (R.styleable.test_testAttr);




ta.getInteger textAttr = int (R.styleable.test_text, -1); Log.e (the TAG, "text =" text + + ", textAttr =" + textAttr); ta.recycle (); }         The second species: namespace method of AttributeSet





ToggleButton public (Context context, attrs) {
Super (context, attrs);
// custom namespace
String namespace = "http://schemas.android.com/apk/res-auto";
// custom background image property
int = switchBackgroundID attrs.getAttributeResourceValue (namespace, "switchBackgroundResource", -1);
// custom slider image properties
int = slideButtonBackgroundID attrs.getAttributeResourceValue (namespace, "slideButtonBackgroundResource", -1);
// custom switching state properties
= attrs.getAttributeBooleanValue the currentState (namespace, "the currentState", to false); setSwitchBackgroundResource (switchBackgroundID); setSlideButtonBackgroundResource (slideButtonBackgroundID); } write values / attrs.xml, wherein the preparation styleable and item labels and other elements <resources>







<DECLARE-styleable name = "the ToggleButton"> <-! background image attribute switch, reference is R.drawable.xx -.> <attr name = "switchBackgroundResource" the format = "Reference" /> <! - closing sliding block image properties, reference is R.drawable.xx -.> <attr name = "slideButtonBackgroundResource" the format = "reference" /> <-! attribute of the current switching state, true open, Close false -> <attr name = "the currentState" the format = "Boolean" /> </ DECLARE-styleable> </ Resources> the CustomView using custom layout file attributes (note namespace) <the RelativeLayout xmlns: = Android " http://schemas.android.com/apk/res/android " xmlns: Tools =" http://schemas.android.com/tools " xmlns:zhy="http://schemas.android.com/apk/res/com.example.test" android:layout_width="match_parent"
















android:layout_height="match_parent" >

<com.example.test.MyTextView
android:layout_width="100dp"
android:layout_height="200dp"
zhy:testAttr="520"
zhy:text="helloworld" />

</RelativeLayout>

onMeasure () method of
measuring and setting the width and height setMeasuredDimension controls ()
the onDraw () method of
rendering control Canvas.drawBitmap ()

Fourth, pull down to refresh, the Raja upload
before acquiring view of the aspect, we need to call the measure () method to measure

Fifth, the event distribution mechanism
// distribute event
dispatchTouchEvent
// intercept events
onInterceptTouchEvent
// handle events
onTouchEvent

 
Android slip events conflict

First, we assume that such a scenario: a ViewPager nested inside a ViewPager, internal and external sliding direction as the sliding direction, how to solve this conflict it? 
Both solutions are given for the slide conflict here: the external interception method, internal intercept method.

Method intercept external
scenario: a ViewPager the Listview a nested, around a slide, a slide up and down. This time we can use external intercept method to deal with conflict. ViewPager in the parent vessel, the rewriting onInterceptTouchEvent () method is determined when the sliders to intercept events, slide up and down is not intercepted, the child elements referred Listview event to process. First, we need to override a ViewPager, called MyViewPager, then rewrite onInterceptTouchEvent () method. Specific code as follows:


1 public class MyViewPager extends ViewPager {
2 private int startX;
3 private int startY;
4 public MyViewPager(Context context) {
5 super(context);
6 }
7
8
9 @Override
10 public boolean onInterceptTouchEvent(MotionEvent ev) {
11 switch (ev.getAction())
12 {
13 case MotionEvent.ACTION_DOWN:
14 startX= (int) ev.getX();
15 startY= (int) ev.getY();
16 break;
17 case MotionEvent.ACTION_MOVE:
18
19 int dX= (int) (ev.getX()-startX);
20 int dY= (int) (ev.getY()-startX);
21 if(Math.abs(dX)>Math.abs(dY)){//左右滑动
22 return true;
23 }else {//上下滑动
24 return false;
25 }
26 case MotionEvent.ACTION_UP:
27 break;
28 }
29 return super.onInterceptTouchEvent(ev);
30 }
31 }

This would solve the conflict sliding in this case, the program demonstrates the following figure: 

 

It said code is a typical external interception logic, need only rewrite onInterceptTouchEvent () method, to the parent container modification event currently requires.

 

Internal Interception Method
scenario: a ViewPager ViewPager a nested, two are left and right sliding. This time we can use the internal intercept method to deal with conflict. That rewrite child elements dispatchTouchEvent () method, and call getParent (). RequestDisallowInterceptTouchEvent (true) is the father of the child container can not intercept events required elements. Let's look at specific code:


1 public boolean dispatchTouchEvent(MotionEvent event) {
2 ...
3
4 switch (action) {
5 case MotionEvent.ACTION_MOVE:
6 getParent().requestDisallowInterceptTouchEvent(true);
7
8 break;
9 case MotionEvent.ACTION_MOVE:
10 if(子元素需要处理此事件)
11 getParent().requestDisallowInterceptTouchEvent(true);
12
13 break;
14 case MotionEvent.ACTION_UP: {
15 break;
16 }
17 ...
18 return super.dispatchTouchEvent(event);
19 ;
20 }

Of course, also you need to modify the parent container onInterceptTouchEvent () method, as follows:


1 @Override
2 public boolean onInterceptTouchEvent(MotionEvent ev) {
3
4 int action=ev.getAction();
5 if(action==MotionEvent.ACTION_DOWN){
6 return false;
7 }else {
8 return true;
9 }
10 }

Run results shown in Figure:

 

These are the two solutions slide conflict solution.

Source: http://www.cnblogs.com/yxx123/p/5250101.html
six, ViewDragHelper
process control problems in the drag interface, sliding helper
public DragLayout (the Context context, AttributeSet attrs, int defStyle) {
Super ( context, attrs, defStyle);
// Create ViewDragHelper auxiliary class 1.
mHelper = ViewDragHelper.create (the this, 1.0f, the callback);
} ViewDragHelper.Callback the callback = new new ViewDragHelper.Callback () { / ** *. 1. the return value, determines whether the child can be dragged * / @Override public Boolean tryCaptureView (View child, int pointerId) { // the user drags the sub-child View // pointerId multi-touch finger ID System.out.println ( "tryCaptureView:"); return to true; } / **















* 2 range drag return a return value> 0, determines the length of the animation, when executed, whether in the horizontal direction can be slid open.
* /
@Override
public int getViewHorizontalDragRange (View Child) {
return M Range The;
} / ** * 3. the child View position correction in the horizontal direction. At this time, has not really moved. the return value will be moved to the determined position View * / @Override public int clampViewPositionHorizontal (child View, int left, int DX) { IF (Child == mMainContent) { left = fixLeft (left); } return left; } / ** * 4. Called when the control position changes, you can do: update accompanied by animation, the state, the callback events. * / @ override public void onViewPositionChanged (View changedView, int left, int Top, int DX, Dy int) { IF (changedView == mLeftContent) {



















// If the mobile is left panel
@ 1 to its original position
mLeftContent.layout (0, 0, 0 + mWidth, mHeight + 0);
// 2. the variation amount dx is transmitted to the left of panel main panel
int newLeft mMainContent.getLeft = () + DX; // left correction value. newLeft = fixLeft (newLeft); mMainContent.layout (newLeft, 0, + mWidth newLeft, mHeight + 0); } dispatchDragEvent (); // for compatibility with earlier versions, the interface manually redrawing all contents. the invalidate (); } / ** * 5. decided to let go of the things to do after the end of the animation * / @Override public void onViewReleased (View releasedChild, float xVel, a float Yvel) { super.onViewReleased (releasedChild, xVel, Yvel); System.out.println ( "onViewReleased: xVel:" + xVel);



















// releasedChild released child
// xvel horizontal velocity to right + left is -
IF (xVel == 0 && mMainContent.getLeft ()> * M Range The 0.5f) {
Open ();
} the else IF ( xVel> 0) {
Open ();
} the else {
Close ();
}
} };

Seven, custom
step (a) custom control
from the control class defines which class needs to inherit?
View, ViewGroup, FrameLayout. . .
Implement three construction methods
under the circumstances override method
onDraw (), onMeasure (), onLayout ()
handle touch events
onTouchEvent (): Click event
OnScrollListener: sliding listening
to intercept events: onInterceptTouchEvent ()
to set callback listeners
when in an action It requires a callback method for processing respective

(B) other cases:
inherit a control (such as ListView), the control methods specific to rewrite, to the effect of superimposed on its basis
there is a: do not call custom controls, write code that is completely pure control LayoutParams, addView (titleLayout) and so on.

Species (three) Custom Control:
a combination of controls, the existing control effect superimposed
on an existing control function superposition
fully customizable

(Iv) Gets the width and height

We highly as an example: 
Android provides two API to dynamically obtain high-View:

view.getMeasuredHeight ()
view.getHeight ()
then the difference between these two API what is it?

It is simply:

view.getMeasuredHeight () is assigned by the view of the measurement method, the value contained hidden height (such as a section view beyond the screen, he will be calculated).
view.getHeight () is subtracted from the position of the top view of the bottom position, i.e. the actual height of View of the display does not include a hidden height.
1. Active Measurement
Code:

view.measure (0, 0);
view.getMeasuredWidth ();
view.getMeasuredHeight ();
Description: 
onMeasure two parameters are passed by the size of the parent control, 
may also be used View.MeasureSpec.makeMeasureSpec (0, mode) ; setting value 
which mode can be selected

MeasureSpec.UNSPECIFIED not specified size, such as the size is determined by the parent listview control
MeasureSpec.EXACTLY match_parent or for a specific value (determination value)
MeasureSpec.AT_MOST suitable wrap_content uncertainty (maximum value)
Note: 
This method does not necessarily measure the correct value because onMesure called many times (due onMesure from top to bottom, the parent control if the child controls for width and height are not satisfied, that as a child control is no limit width and height, the parent control will recall onMesure re-measurement), the measurement results are not necessarily correct.

About measuring time

2. Use OnPreDrawListener

3. Use OnGlobalLayoutListener

4. Use OnLayoutChangeListener

 

Guess you like

Origin www.cnblogs.com/mesaz/p/11141320.html
Recommended