사용자 정의 뷰에서 버튼 만들기

14942 단어 Android
예를 들어 다음 버튼을 만들고 싶습니다.

기본 단추도 아이콘을 추가할 수 있을 것 같지만 복잡한 레이아웃을 만들 수 없을 것 같습니다.
따라서 사용자 정의 보기로 실현할 수 있다.

레이아웃 작성


먼저 단추로 사용할 사용자 정의 보기의 레이아웃 파일을 만듭니다.

노선 배치는 무엇이든지 가능하며 이번에는 ConstraintLayout을 사용했다.
다음에 이 레이아웃을 단추의 모양으로 설정합니다.
프로그램은 루트 레이아웃의 스타일 속성에 단추 스타일을 설정하기만 하면 됩니다.
<!-- view_custom_buttom.xml -->

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    style="@style/Widget.AppCompat.Button">
    <!-- ↑ここ! -->

    ...

</android.support.constraint.ConstraintLayout>
이렇게 하면 버튼과 똑같아 보이고 눌렀을 때의 문양도 기본 상황과 똑같아진다.

사용자 정의 보기 카테고리 만들기


다음에 사용자 정의 보기 종류를 만듭니다.
// CustomButtonView.java

public class CustomButtonView extends ConstraintLayout {
    public CustomButtonView(Context context) {
        this(context, null);
    }

    public CustomButtonView(Context context, AttributeSet attrs) {
        super(context, attrs);

        init();
    }

    private void init() {
        LayoutInflater.from(getContext()).inflate(R.layout.view_custom_button, this);
    }
}

완성


이 경우 Activity는 잠시 포함됩니다.
<!-- activity_main.xml -->

....

<***.***.CustomButtonView
        android:id="@+id/custom_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

...
onClick도 청중을 설정합니다.
// MainActivity.java

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // インスタンスを取得
        CustomButtonView customButton = findViewById(R.id.custom_button);

        // onClickにリスナーを設定
        customButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity.this, "Click!", Toast.LENGTH_LONG).show();
            }
        });
    }
}
그렇다면 이렇게 하면 순조롭게 진행될 것 같지만 돌려보면 사용자 정의 버튼을 눌러도 온클릭 청취자에게 불려가지 않는다.
조사해 보니 아래의 보도가 참고가 되었다.
CustomView의 OnClick이 반응하지 않을 때의 처리 방법 - Qita
사용자 정의 뷰에서 OnClick 처리는 직접 작성해야 합니다.

CustomButonView에서 onClick 처리 추가


상기 문장을 참고하여 다음과 같은 내용을 첨가하다.
// CustomButtonView.java

public class CustomButtonView extends ConstraintLayout {
    ...

    @Nullable
    private OnClickListener listener;

    @Override
    public void setOnClickListener(@Nullable OnClickListener l) {
        this.listener = l;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_UP) {
            if (listener != null) {
                post(new Runnable() {
                    @Override
                    public void run() {
                        listener.onClick(CustomButtonView.this);
                    }
                });
            }
        }

        return super.dispatchTouchEvent(ev);
    }
}

이렇게 하면 온클릭이 도망갈 수 있어.

버튼 범위 밖으로 이동할 때의 동작 수정


이렇게 하면 완성될 것 같지만 기본 버튼과는 미묘한 움직임이 있다.
가볍게 두드리기
  • 버튼
  • 버튼을 누르면서 손가락을 버튼 범위 밖으로 이동
  • 화면을 멀리
  • 위의 절차에 따라 기본 단추는 onClick이 발생하지 않지만, 제작된 Custom ButtonView에서는 이벤트가 발생합니다.
    이 항목을 수정하려면 ACTION_UP 의 좌표가 단추의 범위 내에 있는지, 범위 내에서만 청중을 부르는지 확인하십시오.
    // CustomButtonView.java
    
    class CustomButtonView extends ConstraintLayout {
        ...
    
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            if (ev.getAction() == MotionEvent.ACTION_UP) {
                // 範囲内のチェックを追加
                if (listener != null && checkInside(ev)) {
                    post(new Runnable() {
                        @Override
                        public void run() {
                            listener.onClick(CustomButtonView.this);
                        }
                    });
                }
            }
    
            return super.dispatchTouchEvent(ev);
        }
    
        private boolean checkInside(MotionEvent ev) {
            int[] point = new int[2];
    
            getLocationOnScreen(point);
    
            int x = point[0];
            int y = point[1];
    
            return (ev.getRawX() >= x && ev.getRawX() <= x + getWidth()) &&
                    (ev.getRawY() >= y && ev.getRawY() <= y + getHeight());
        }
    }
    

    후편 완성!


    이렇게 하면 외관과 동작이 기본 단추와 기본적으로 같은 사용자 정의 보기 단추를 만들 수 있다.

    좋은 웹페이지 즐겨찾기