안드로이드:onClick XML 속성은 setOnClickListener와 정확히 어떻게 다릅니까?
당신이 할당할 수 있는 것을 읽었습니다.onClick
두 가지 방법으로 버튼을 조작합니다.
android:onClick
입니다.void name(View v)
또는를여하사를 하여.setOnClickListener
을 OnClickListener
인터페이스후자는 종종 내가 개인적으로 좋아하지 않는 익명의 클래스(개인적 취향) 또는 구현하는 내부 클래스를 정의하는 것을 요구합니다.OnClickListener
.
XML 속성을 사용하면 클래스 대신 메서드를 정의할 수 있으므로 XML 레이아웃이 아닌 코드를 통해 동일한 작업을 수행할 수 있는지 궁금합니다.
아니요, 코드로는 불가능합니다.는 Android를 할 뿐입니다.OnClickListener
할 때 할 수 .android:onClick="someMethod"
기여하다.
이 두 코드 스니펫은 동일하며, 두 가지 다른 방식으로 구현될 뿐입니다.
코드 구현
Button btn = (Button) findViewById(R.id.mybutton);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myFancyMethod(v);
}
});
// some more code
public void myFancyMethod(View v) {
// does something very interesting
}
는 위다음코구다니현입의 입니다.OnClickListener
이것이 바로 XML 구현입니다.
XML 구현
<?xml version="1.0" encoding="utf-8"?>
<!-- layout elements -->
<Button android:id="@+id/mybutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click me!"
android:onClick="myFancyMethod" />
<!-- even more layout elements -->
백그라운드에서 Android는 클릭 이벤트에서 메서드를 호출하면서 Java 코드 외에는 아무것도 하지 않습니다.
는 "XML", "Android", "Android"를.onClick
법myFancyMethod()
현재 활동에서만 가능합니다.fragment를 는 fragment를 때문에 fragment를 하는 경우 이 .onClick
의법에 있는 .java
XML을 하는 데 입니다.
제가 주목한 또 다른 중요한 것은.당신은 익명의 방법을 선호하지 않는다고 말했습니다.당신은 익명 수업을 싫어한다는 뜻이었어요.
제가 최고의 답변을 보았을 때, 제 문제가 매개변수(View v)를 화려한 방법에 두지 않는 것이라는 것을 깨달았습니다.
public void myFancyMethod(View v) {}
xml에서 액세스할 때는 다음을 사용해야 합니다.
android:onClick="myFancyMethod"/>
android:onClick
API 레벨 4 이후를 위한 것이므로 < 1.6>을 목표로 한다면 사용할 수 없습니다.
방법을 공개하는 것을 잊었는지 확인하십시오!
지정android:onClick
는 성과결입니다.Button
호출 인턴호출setOnClickListener
.따라서 전혀 차이가 없습니다.
이해를 및 XML에 .onClick
속성이 프레임워크에서 처리됩니다.
레이아웃 파일이 부풀려지면 해당 파일에 지정된 모든 보기가 인스턴스화됩니다.에는 이특한경우에정,에,Button
생성자를 사용하여 인스턴스를 만듭니다.XML 태그의 모든 특성은 리소스 번들에서 읽혀지고 다음과 같이 전달됩니다.AttributeSet
생성자에게.
Button
는 클스가상에서 됩니다.View
결과적으로 생기는 수업View
입니다. 합니다.setOnClickListener
.
attrs.xml에 정의된 onClick 특성은 View.java에서 다음과 같이 참조됩니다.R.styleable.View_onClick
.
여기 전화로 대부분의 작업을 수행하는 코드가 있습니다.setOnClickListener
저절로
case R.styleable.View_onClick:
if (context.isRestricted()) {
throw new IllegalStateException("The android:onClick attribute cannot "
+ "be used within a restricted context");
}
final String handlerName = a.getString(attr);
if (handlerName != null) {
setOnClickListener(new OnClickListener() {
private Method mHandler;
public void onClick(View v) {
if (mHandler == null) {
try {
mHandler = getContext().getClass().getMethod(handlerName,
View.class);
} catch (NoSuchMethodException e) {
int id = getId();
String idText = id == NO_ID ? "" : " with id '"
+ getContext().getResources().getResourceEntryName(
id) + "'";
throw new IllegalStateException("Could not find a method " +
handlerName + "(View) in the activity "
+ getContext().getClass() + " for onClick handler"
+ " on view " + View.this.getClass() + idText, e);
}
}
try {
mHandler.invoke(getContext(), View.this);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Could not execute non "
+ "public method of the activity", e);
} catch (InvocationTargetException e) {
throw new IllegalStateException("Could not execute "
+ "method of the activity", e);
}
}
});
}
break;
당신이 볼 수 있듯이.setOnClickListener
코드에서와 같이 콜백을 등록하기 위해 호출됩니다.유일한 차이점은 사용한다는 것입니다.Java Reflection
활동에 정의된 콜백 방법을 호출합니다.
다음은 다른 답변에서 언급된 문제의 이유입니다.
- 콜백 메서드는 public이어야 합니다: 를 사용하므로 public access specifier가 있는 함수만 검색됩니다.그렇지 않으면 처리할 준비가 되어 있습니다.
IllegalAccessException
예외. - onClick in Fragment와 함께 버튼을 사용하는 동안 콜백은 Activity:
getContext().getClass().getMethod()
호출은 메서드 검색을 현재 컨텍스트(Fragment의 경우 활동)로 제한합니다.따라서 메서드는 Fragment 클래스가 아닌 Activity 클래스 내에서 검색됩니다. - 콜백 메서드는 View 매개 변수를 수락해야 합니다: 수락하는 메서드를 검색하기 때문입니다.
View.class
매개 변수로
여기에 매우 좋은 답변이 있습니다. 하지만 한 줄을 추가하고 싶습니다.
android:onclick
XML에서 Android는 이를 처리하기 위해 장면 뒤의 Java 반사를 사용합니다.
여기서 설명하는 바와 같이, 반사는 항상 성능을 저하시킵니다.(특히 Dalvik VM에서). 등록 중onClickListener
그게 더 좋은 방법입니다.
onClick XML 기능을 사용하려면 해당 메서드에 XML 개체와 유형이 일치하는 매개 변수가 하나 있어야 합니다.
예를 들어 버튼은 이름 문자열을 통해 메서드에 연결됩니다.android:onClick="MyFancyMethod"
은 다음과 같이 표시되어야 ....MyFancyMethod(View v) {...
이 기능을 메뉴 항목에 추가하려는 경우 XML 파일의 구문은 동일하지만 메서드는 다음과 같이 선언됩니다....MyFancyMethod(MenuItem mi) {...
온클릭 리스너를 설정하는 또 다른 방법은 XML을 사용하는 것입니다.Android:onClick 속성을 태그에 추가하기만 하면 됩니다.
가능하면 익명 Java 클래스에 "onClick" xml 특성을 사용하는 것이 좋습니다.
먼저 코드의 차이점을 살펴보겠습니다.
XML 특성 / onClick 특성
XML 부분
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button1"
android:onClick="showToast"/>
자바 부분
public void showToast(View v) {
//Add some logic
}
익명 Java 클래스 / setOnClickListener
XML 부분
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
자바 부분
findViewById(R.id.button1).setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
//Add some logic
}
});
익명 Java 클래스에 비해 XML 특성을 사용할 경우의 이점은 다음과 같습니다.
- Anonymous Java 클래스에서는 항상 요소에 대한 id를 지정해야 하지만 XML 속성 id는 생략할 수 있습니다.
- Anonymous Java 클래스에서는 뷰 내부의 요소(findViewById 부분)를 적극적으로 검색해야 하지만 XML 속성을 사용하면 Android가 대신 검색할 수 있습니다.
- 익명 Java 클래스는 보시는 바와 같이 최소 5줄의 코드가 필요하지만 XML 속성을 사용하면 3줄의 코드로 충분합니다.
- Anonymous Java 클래스를 사용하면 메서드의 이름을 "onClick"으로 지정해야 하지만 XML 속성을 사용하면 원하는 이름을 추가할 수 있으므로 코드의 가독성에 큰 도움이 됩니다.
- Xml "onClick" 특성은 API 레벨 4 릴리스 동안 Google에 의해 추가되었으며, 이는 약간 더 현대적인 구문이며 거의 항상 현대적인 구문이 더 낫다는 것을 의미합니다.
물론 Xml 속성을 항상 사용할 수 있는 것은 아닙니다. 다음은 Xml 속성을 선택하지 않은 이유입니다.
- 만약 우리가 파편으로 작업하고 있다면요.onClick 속성은 활동에만 추가할 수 있으므로, fragment가 있으면 익명 클래스를 사용해야 합니다.
- onClick 수신기를 별도의 클래스로 이동하려는 경우(매우 복잡하거나 응용프로그램의 다른 부분에서 다시 사용하려는 경우) xml 특성도 사용하지 않습니다.
Java 8을 사용하면 Method Reference를 사용하여 원하는 작업을 수행할 수 있습니다.
이것이 당신의 것이라고 가정합니다.onClick
버튼의 이벤트 핸들러입니다.
private void onMyButtonClicked(View v) {
if (v.getId() == R.id.myButton) {
// Do something when myButton was clicked
}
}
다음, 신당, 은럼을 합니다.onMyButtonClicked
턴) 서드조에 있는 :setOnClickListener()
이렇게 부르세요.
Button myButton = (Button) findViewById(R.id.myButton);
myButton.setOnClickListener(this::onMyButtonClicked);
이렇게 하면 스스로 익명 클래스를 명시적으로 정의하지 않아도 됩니다.하지만 자바 8의 메소드 레퍼런스는 사실 구문론적인 설탕에 불과하다는 것을 강조해야 합니다.실제로는 람다 식과 마찬가지로 익명 클래스의 인스턴스를 생성하므로 이벤트 핸들러를 등록 취소할 때 람다 식 스타일 이벤트 핸들러와 유사한 주의가 적용되었습니다.이 기사는 그것을 정말 좋게 설명합니다.
PS. 안드로이드에서 자바 8 언어 기능을 정말 어떻게 사용할 수 있는지 궁금해하는 사람들을 위해, 이것은 retrolambda 라이브러리의 예의입니다.
XML 속성을 사용하면 클래스 대신 메서드를 정의할 수 있으므로 XML 레이아웃이 아닌 코드를 통해 동일한 작업을 수행할 수 있는지 궁금합니다.
예, 당은당을 수 .fragment
또는activity
View.OnClickListener
코드에서 새 보기 개체를 초기화할 때 간단히 수행할 수 있습니다.mView.setOnClickListener(this);
뷰 되어 사용됩니다.onClick(View v)
이 사용하는 .fragment
또는activity
등이 가지고 있습니다.
어떤 견해가 그것을 불렀는지 구별하기 위해.onClick
switch 문을 할 수 .v.getId()
방법.
이 답변은 "아니오, 코드로는 불가능합니다"라는 답변과 다릅니다.
Add Button in xml and give onclick attribute name that is the name of Method.
<!--xml --!>
<Button
android:id="@+id/btn_register"
android:layout_margin="1dp"
android:onClick="addNumber"
android:text="Add"
/>
Button btnAdd = (Button) findViewById(R.id.mybutton); btnAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
addNumber(v);
}
});
Private void addNumber(View v){
//Logic implement
switch (v.getId()) {
case R.id.btnAdd :
break;
default:
break;
}}
루이보의 답변을 뒷받침하듯, 네, 클릭하면 안드로이드 XML에서 사용할 수 있는 방법을 "퍼블릭"으로 선언해야 합니다. 저는 API 레벨 8(minSdk...)에서 16(targetSdk...)까지 앱을 개발하고 있습니다.
저는 제 방식을 비공개로 선언하고 있었는데, 오류가 발생하여 공공사업이 훌륭하다고 선언했습니다.
요, android:onClick
클릭을 데인 XML을 사용하는 것 .setOnClickListener
를 추가하는 것보다 더 많은 것을 합니다.onClickListener
실제로, 그것은 뷰 속성을 넣었습니다.clickable
사실대로
대부분의 Android 구현에서는 문제가 없을 수 있지만 전화기 생성자에 따르면 버튼은 항상 클릭 가능 = true로 기본 설정되지만 일부 전화기 모델의 다른 생성자는 버튼이 아닌 보기에서 기본 클릭 가능 = false로 설정될 수 있습니다.
만으로는 충분하지 "XML"을 . 항상 추가해야 합니다.android:clickable="true"
아닌 , = 가 있고 이 하는 것을 한 도 잊어버린 할 때 수 ! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 런타임에 문제를 인식하지 못하고 고객이 언제 문제를 해결할 수 있는지에 대한 피드백을 받을 수 있습니다.
또한 proguard가 XML 속성과 클래스 메서드를 어떻게 난독화하고 이름을 바꾸는지 확신할 수 없기 때문에 100% 안전하지 않기 때문에 언젠가 버그가 발생하지 않을 것입니다.
그러니 절대로 문제를 일으키고 싶지 않고 절대로 생각하지 않는다면, 사용하는 것이 좋습니다.setOnClickListener
주석이 할 수 있습니다.@OnClick(R.id.button)
와 같은 하려고 합니다.main.xml
<Button
android:id="@+id/btn_register"
android:layout_margin="1dp"
android:layout_marginLeft="3dp"
android:layout_marginTop="10dp"
android:layout_weight="2"
android:onClick="register"
android:text="Register"
android:textColor="#000000"/>
java 파일에서 당신은 이 방법과 같은 방법을 써야 합니다.
public void register(View view) {
}
나는 xml 파일에 이 코드를 씁니다...
<Button
android:id="@+id/btn_register"
android:layout_margin="1dp"
android:layout_marginLeft="3dp"
android:layout_marginTop="10dp"
android:layout_weight="2"
android:onClick="register"
android:text="Register"
android:textColor="#000000"/>
그리고 이 코드를 단편적으로 쓰시오...
public void register(View view) {
}
가장 좋은 방법은 다음 코드를 사용하는 것입니다.
Button button = (Button)findViewById(R.id.btn_register);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//do your fancy method
}
});
setOnClicklistener()의 익명 클래스를 사용하지 않고 보다 쉽게 사용할 수 있도록 보기를 구현합니다.클릭 수신기 인터페이스에서 아래와 같이 선택합니다.
public class 사용자 클래스는 Common Activity 구현 보기를 확장합니다.ClickListener에서...
이렇게 하면 다음을 피할 수 있습니다.
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
yourMethod(v);
}
});
바로 다음 위치로 이동합니다.
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.your_view:
yourMethod();
break;
}
}
언급URL : https://stackoverflow.com/questions/4153517/how-exactly-does-the-androidonclick-xml-attribute-differ-from-setonclicklistene
'programing' 카테고리의 다른 글
pyproject.toml 파일은 무엇을 위한 것입니까? (0) | 2023.06.08 |
---|---|
입력을 테스트하고 있습니다.효소의 초점() (0) | 2023.06.08 |
행렬도:lib getylim 값 (0) | 2023.06.08 |
wordpress 포스트 유효성 검사 추가 (0) | 2023.06.08 |
Python을 사용하여 PowerPivot 모델에서 원시 데이터 추출 (0) | 2023.06.08 |