Android 캡 처 이벤트 범위 클릭 방법
여기 서 문 제 를 발견 하고 문 제 를 처리 하 는 과정 을 기록 해 보 세 요.
이러한 ViewGroup,layot 두 개의 선형 레이아웃 을 사용자 정의 합 니 다.왼쪽 LinearLayout 는 전체 화면 을 덮어 쓰 고 오른쪽 LinearLayout 는 화면 밖 에 숨 깁 니 다.그 다음 에 미 끄 러 지 려 는 과정 에서 두 번 째 LinearLayout 가 나타 나 는 과정 에서 버튼 버튼 버튼 과 두 번 째 선형 구조의 위치 정 보 를 관찰 합 니 다.
왼쪽 으로 두 번 째 선형 천 을 미 끄 러 뜨리 는 과정 에서 그의 위 치 는 변 하지 않 았 음 을 알 수 있다.여기 서 getLeft(),getTop(),getRight(),getBottom()을 통 해 얻 은 위 치 를 말한다.즉,layot 가 결정 하 는 위 치 를 말한다.
위치 가 바 뀌 지 않 았 으 니 이 럴 때 두 번 째 선형 레이아웃 과 단 추 를 누 르 면 이벤트 가 응답 합 니 다.이 는 이벤트 의 위 치 를 캡 처 하 는 것 이 layot 의 위치 가 아니 라 는 것 을 의미 합 니 다.화면 밖으로 손 을 내밀 고 클릭 하지 않 았 기 때문에...
ViewGroup\#dispatchTouchEvent 방법 을 돌 이 켜 보면 터치 이 벤트 를 나 눠 줄 때:
for (int i = count - 1; i >= 0; i--) {
final View child = children[i];
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE
|| child.getAnimation() != null) {
child.getHitRect(frame);
if (frame.contains(scrolledXInt, scrolledYInt)) {
// offset the event to the view's coordinate system
final float xc = scrolledXFloat - child.mLeft;
final float yc = scrolledYFloat - child.mTop;
ev.setLocation(xc, yc);
child.mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT;
if (child.dispatchTouchEvent(ev)) {
// Event handled, we have a target now.
mMotionTarget = child;
return true;
}
}
}
그 중에서 frame.contains(scrolledXInt,scrolledYInt)함 수 는 바로 판단 점(scrolledXInt,scrolledYInt)이 frame 사각형 안에 있 는 지 아 닌 지 를 판단 하 는 것 입 니 다.이 직사각형 frame 은 child.getHitRect(frame)입 니 다.획득:
public void getHitRect(Rect outRect) {
outRect.set(mLeft, mTop, mRight, mBottom);
}
분명히 이 사각형 은 이 하위 View 의 Layout 레이아웃 매개 변수 에 의 해 결정 된다.그러나 scrolledXInt 와 scrolledYInt 인 자 는 우리 가 손가락 으로 클릭 한 위치 가 아 닙 니 다.
final int action = ev.getAction();
final float xf = ev.getX();
final float yf = ev.getY();
final float scrolledXFloat = xf + mScrollX;
final float scrolledYFloat = yf + mScrollY;
……
final int scrolledXInt = (int) scrolledXFloat;
final int scrolledYInt = (int) scrolledYFloat;
이 점 이 하위 뷰 에 포함 되 어 있 는 지 판단 할 때 이 점 은 손가락 이 클릭 한 좌표 가 아니 라 손가락 이 클릭 한 좌표 에 mScrollX 와 mScrolly 를 더 한 다음 에 이 하위 뷰 의 범위 안에 있 는 지 판단 하 는 것 을 알 수 있다.현재 왼쪽으로 미 끄 러 지 는 과정 에서 두 번 째 선형 구조의 위 치 는 변 하지 않 았 지만 layot 의 매개 변수 위 치 는 mLeft:720,mTop:0,mRight:1440,mBottom:1134 이다.
그러나 그의 아버지 View 의 mScrollX 가 바 뀌 었 다.왼쪽으로 미 끄 러 지 는 mScrollX 는 0 보다 크다.이것 은 손 으로 두 번 째 선형 구 조 를 클릭 하고 손 이 클릭 한 위치 에 mScrollX 의 값 을 더 하면 두 번 째 선형 구조의 layot 범위 에 떨어진다.
테스트 코드:
사용자 정의 MyViewGroup:
public class MyViewGroup extends ViewGroup {
public static final String TAG = "MyViewGroup";
private int childCount;
private GestureDetector detector;
private Button btn;
private LinearLayout ll2;
public MyViewGroup(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public MyViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public MyViewGroup(Context context) {
super(context);
init(context);
}
private void init(final Context context) {
detector = new GestureDetector(context, new MyOnGestureListener());
LinearLayout ll1 = new LinearLayout(context);
ll1.setBackgroundColor(Color.BLUE);
ll2 = new LinearLayout(context);
ll2.setBackgroundColor(Color.RED);
btn = new Button(context);
btn.setText(" ");
ll2.addView(btn);
addView(ll1);
addView(ll2);
setOnTouchListener(new MyTouchEvent());
ll2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, " 2", 0).show();
}
});
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context, " Button", 0).show();
}
});
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
child.measure(widthMeasureSpec,heightMeasureSpec);
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
child.layout(0+i*getWidth(), 0, (i+1)*getWidth(), getHeight());
}
}
private class MyTouchEvent implements View.OnTouchListener{
@Override
public boolean onTouch(View v, MotionEvent event) {
detector.onTouchEvent(event);
return true;
}
}
private class MyOnGestureListener extends SimpleOnGestureListener{
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
scrollBy((int) distanceX, 0);
if (getScrollX()% 10 == 0) {
Log.i(TAG, "Button :" + btn.getLeft() + "/"
+ btn.getTop() + "/"
+ btn.getRight() + "/"
+ btn.getBottom());
Log.i(TAG, " 2 :" + ll2.getLeft() + "/"
+ ll2.getTop() + "/"
+ ll2.getRight() + "/"
+ ll2.getBottom());
Log.i(TAG, "MyViewGroup mScrollX:" + getScrollX());
}
return super.onScroll(e1, e2, distanceX, distanceY);
}
}
}
그리고 Activity 에서:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyViewGroup(this));
}
}
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.