내 Android 앱에 onClick 이벤트가있는 버튼처럼 사용하고있는 imageview가 있지만 클릭 할 때 imageview에 클릭 가능한 효과를주지 않는다고 짐작할 수 있습니다. 어떻게 할 수 있습니까?
답변:
클릭 / 비 클릭 상태에 대해 서로 다른 이미지를 디자인하고 다음과 같이 onTouchListener에서 설정할 수 있습니다.
final ImageView v = (ImageView) findViewById(R.id.button0);
v.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
switch (arg1.getAction()) {
case MotionEvent.ACTION_DOWN: {
v.setImageBitmap(res.getDrawable(R.drawable.img_down));
break;
}
case MotionEvent.ACTION_CANCEL:{
v.setImageBitmap(res.getDrawable(R.drawable.img_up));
break;
}
}
return true;
}
});
더 나은 선택은 다음과 같이 선택자를 정의하는 것입니다.
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true"
android:drawable="@drawable/img_down" />
<item android:state_selected="false"
android:drawable="@drawable/img_up" />
</selector>
이벤트에서 이미지를 선택하십시오.
v.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
v.setSelected(arg1.getAction()==MotionEvent.ACTION_DOWN);
return true;
}
});
MotionEvent.ACTION_DOWN || MotionEvent.ACTION_MOVE
만큼 우리가 눌러있는 것처럼 보여주는 이미지를 유지하기 위해.
setOnTouchListener(...
. 간단하게 생성 한 <selector ...>
다음 XML에서 클릭 가능한 ImageView를 설정할 수 있습니다.<ImageView ... android:clickable="true" android:focusable="true" android:src="@drawable/my_selector" />
다음과 같이 단일 이미지로이를 수행 할 수 있습니다.
//get the image view
ImageView imageView = (ImageView)findViewById(R.id.ImageView);
//set the ontouch listener
imageView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
ImageView view = (ImageView) v;
//overlay is black with transparency of 0x77 (119)
view.getDrawable().setColorFilter(0x77000000,PorterDuff.Mode.SRC_ATOP);
view.invalidate();
break;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL: {
ImageView view = (ImageView) v;
//clear the overlay
view.getDrawable().clearColorFilter();
view.invalidate();
break;
}
}
return false;
}
});
더 쉽게 재사용 할 수 있도록 ImageView의 하위 클래스 (또는 ImageView의 하위 클래스 인 ImageButton)로 만들 것입니다. 그러나 이렇게하면 "선택된"모양을 imageview에 적용 할 수 있습니다.
false
그렇지 않으면 뷰의 실제, onClick()
이벤트가 발생되지 않습니다
그것은 함께 할 수있어 하나의 이미지 파일 ColorFilter 방법을 사용. 그러나 ColorFilter는 버튼이 아닌 ImageView와 함께 작동 할 것으로 예상하므로 버튼을 ImageView로 변환해야합니다. 어쨌든 이미지를 버튼으로 사용하는 경우 문제가되지 않지만 텍스트가 있으면 더 짜증이납니다 ... 어쨌든 텍스트 문제를 해결하는 방법을 찾은 경우 사용할 코드는 다음과 같습니다.
ImageView button = (ImageView) findViewById(R.id.button);
button.setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
그러면 버튼에 빨간색 오버레이가 적용됩니다 (색상 코드는 완전히 불투명 한 빨간색의 16 진수 코드입니다. 처음 두 자리는 투명성이고 다음은 RR GG BB입니다.)
편집 : 아래의 원래 답변이 작동하고 설정하기 쉽지만 더 효율적인 구현을 원하거나 필요로하는 경우 Google의 Android Developer Advocate 가이 게시물 을 참조하십시오 . 또한 android:foreground
속성은 Android M에서 기본적으로 ImageView를 포함한 모든 뷰 에 제공됩니다.
ImageView에 대한 선택기를 사용할 때의 문제점은보기의 배경으로 만 설정할 수 있다는 것입니다. 이미지가 불투명 한 한 그 뒤에있는 선택기의 효과를 볼 수 없습니다.
트릭은 콘텐츠에 android:foreground
대한 오버레이 를 정의 할 수 있는 속성 을 사용 하여 FrameLayout에 ImageView를 래핑하는 것입니다 . 우리가 설정 한 경우 android:foreground
선택기에 (예 : ?android:attr/selectableItemBackground
API 레벨 11 + 용) 및 첨부 OnClickListener
우리가 원하는 클릭 효과 - 이미지 뷰 대신 FrameLayout이에, 이미지는 우리의 선택의 당김과 중첩 될 것이다!
보다:
<FrameLayout
android:id="@+id/imageButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:foreground="?android:attr/selectableItemBackground" >
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/yourImageFile" />
</FrameLayout>
(이는 부모 레이아웃 내에 있어야합니다.)
final View imageButton = findViewById(R.id.imageButton);
imageButton.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View view) {
// do whatever we wish!
}
});
selectableItemBackground
속성은 API 레벨 11에서만 추가되었으므로 이전 API 레벨에이 솔루션을 사용하려면 다른 선택기를 사용해야합니다. 예를 들어 API 레벨 7을 지원하는 내 애플리케이션 중 하나의 @drawable/list_selector_holo_light
경우 Android Holo Colors Generator 도구를 사용하여 생성 된 리소스를 사용합니다 .
<ImageButton>
selectableItemBackground와 함께 1 개만 사용하여 동일한 동작을 수행 할 수 있습니다 !
사용 스타일 = "안드로이드 : borderlessButtonStyle" XML 파일입니다. Android 기본 클릭 효과가 표시됩니다.
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher"
style="?android:borderlessButtonStyle"
/>
android:adjustViewBounds="true"
패딩을 설정 해제 하는 데 사용 합니다.
style="?android:attr/borderlessButtonStyle"
. developer.android.com/guide/topics/ui/controls/…
ImageButton을 사용하기 만하면 됩니다.
이를 해결하는 간단한 방법은 다음과 같습니다.
ImageView iv = (ImageView) findViewById(R.id.imageView);
iv.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
//Agrega porcentajes de cada fraccion de grafica pastel
Animation animFadein = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.fade_in);
iv.startAnimation(animFadein);
});
파일 res/anim/fade_in.xml
:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true" >
<alpha
android:duration="100"
android:fromAlpha="0.0"
android:interpolator="@android:anim/accelerate_interpolator"
android:toAlpha="1.0" />
</set>
선택 가능한 배경을 ImageView로 설정하고 패딩을 추가합니다. 그런 다음 OnClickListener
.
<ImageView
android:id="@+id/your_image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/your_image"
android:padding="10dp"
android:background="?android:attr/selectableItemBackground"/>
선택기 드로어 블 선택을 정의하기 위해
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true"
android:drawable="@drawable/img_down" />
<item android:state_selected="false"
android:drawable="@drawable/img_up" />
</selector>
android : state_selected 대신 android : state_pressed를 사용해야합니다.
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed ="true"
android:drawable="@drawable/img_down" />
<item android:state_pressed ="false"
android:drawable="@drawable/img_up" />
</selector>
탭했을 때 리플을 원하는 경우 다음 코드로 제공 할 수 있습니다.
<ImageView
...
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
...
</ImageView>
마찬가지로 TextView에 대한 클릭 효과를 구현할 수 있습니다.
<TextView
...
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
...
</TextView>
이것은 나를 위해 일했습니다.
img.setOnTouchListener(new OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
{
((ImageView)v).setImageAlpha(200);
break;
}
case MotionEvent.ACTION_MOVE:
{
// if inside bounds
if(event.getX() > 0 && event.getX() < v.getWidth() && event.getY() > 0 && event.getY() < v.getHeight())
{
((ImageView)v).setImageAlpha(200);
}
else
{
((ImageView)v).setImageAlpha(255);
}
break;
}
case MotionEvent.ACTION_UP:
{
((ImageView)v).setImageAlpha(255);
}
}
return true;
}
});
@Edit : Gunhan이 말했듯이 setImageAlpha 메서드에는 하위 호환성 문제가있을 것입니다. 이 방법을 사용했습니다.
public static void setImageAlpha(ImageView img, int alpha)
{
if(Build.VERSION.SDK_INT > 15)
{
img.setImageAlpha(alpha);
}
else
{
img.setAlpha(alpha);
}
}
나는 비슷한 일을한다.
프레스 효과 도우미보기 :
사용법 : iOS와 같은 간단한 프레스 효과 수행
간단한 사용법 :
ImageView img = (ImageView) findViewById (R.id.img);
위의 모든 답변과 함께 ImageView를 누르고 상태를 변경하고 싶었지만 사용자가 이동하면 "취소"하고 onClickListener를 수행하지 않았습니다.
결국 클래스 내에서 Point 객체를 만들고 사용자가 ImageView를 누를 때 좌표를 설정했습니다. MotionEvent.ACTION_UP에서 새 포인트를 기록하고 포인트를 비교했습니다.
잘 설명 할 수밖에 없지만 여기에 제가 한 일이 있습니다.
// set the ontouch listener
weatherView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// Determine what action with a switch statement
switch (event.getAction()) {
// User presses down on the ImageView, record the original point
// and set the color filter
case MotionEvent.ACTION_DOWN: {
ImageView view = (ImageView) v;
// overlay is black with transparency of 0x77 (119)
view.getDrawable().setColorFilter(0x77000000,
PorterDuff.Mode.SRC_ATOP);
view.invalidate();
p = new Point((int) event.getX(), (int) event.getY());
break;
}
// Once the user releases, record new point then compare the
// difference, if within a certain range perform onCLick
// and or otherwise clear the color filter
case MotionEvent.ACTION_UP: {
ImageView view = (ImageView) v;
Point f = new Point((int) event.getX(), (int) event.getY());
if ((Math.abs(f.x - p.x) < 15)
&& ((Math.abs(f.x - p.x) < 15))) {
view.performClick();
}
// clear the overlay
view.getDrawable().clearColorFilter();
view.invalidate();
break;
}
}
return true;
}
});
imageView에 onClickListener가 설정되어 있지만 메서드가 될 수 있습니다.
MotionEvent.ACTION_CANCEL
동일한 기능을 가진 케이스 를 추가 MotionEvent.ACTION_UP
하면 사용자가 클릭 동작이 아닌 "끌기"를 수행하는 경우보기를 "지울"수 있습니다.
setPressed
onTouchEvent 리스너를 만드는 대신 ImageView에서 재정의 하고 색상 필터링을 수행 할 수 있습니다 .
@Override
public void setPressed(boolean pressed) {
super.setPressed(pressed);
if(getDrawable() == null)
return;
if(pressed) {
getDrawable().setColorFilter(0x44000000, PorterDuff.Mode.SRC_ATOP);
invalidate();
}
else {
getDrawable().clearColorFilter();
invalidate();
}
}
을 바탕으로 씨 죤의 대답 , 내 추상적 인 유틸리티 클래스의 정적 메서드를 사용합니다 :
public abstract class Utility {
...
public static View.OnTouchListener imgPress(){
return imgPress(0x77eeddff); //DEFAULT color
}
public static View.OnTouchListener imgPress(final int color){
return new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN: {
ImageView view = (ImageView) v;
view.getDrawable().setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
view.invalidate();
break;
}
case MotionEvent.ACTION_UP:
v.performClick();
case MotionEvent.ACTION_CANCEL: {
ImageView view = (ImageView) v;
//Clear the overlay
view.getDrawable().clearColorFilter();
view.invalidate();
break;
}
}
return true;
}
};
}
...
}
그런 다음 onTouchListener와 함께 사용합니다.
ImageView img=(ImageView) view.findViewById(R.id.image);
img.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { /* Your click action */ }
});
img_zc.setOnTouchListener(Utility.imgPress()); //Or Utility.imgPress(int_color_with_alpha)
많은 이미지가 있고 XML 드로어 블없이 하나의 이미지 만있는 간단한 onTouch 효과를 원하는 경우 매우 간단합니다.
를 사용 android.widget.Button
하고 background
속성을 android.graphics.drawable.StateListDrawable
. 이 모든 작업은 XML 또는 프로그래밍 방식으로 수행 할 수 있습니다. Form Stuff 튜토리얼 의 Custom Button 섹션을 참조하십시오 .
여기 에 샘플을 만들고 레이아웃에서 ImageView를 ClickableImageView 로 변경 하십시오. 도움이 되었기를 바랍니다.
배경 이미지를 사용하면 더 많은 뷰티 솔루션이 있습니다. :)
public static void blackButton(View button){
button.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
v.getBackground().setColorFilter(0xf0f47521,PorterDuff.Mode.SRC_ATOP);
v.invalidate();
break;
}
case MotionEvent.ACTION_UP: {
v.getBackground().clearColorFilter();
v.invalidate();
break;
}
}
return false;
}
});
}
또는:
이 양식을 이미지 버튼과 함께 사용할 수 있습니다.
파일 생성 res/drawable/btn_video.xml
:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/image"
android:state_pressed="true" />
<item android:drawable="@drawable/ico2"
android:state_focused="true" />
<item android:drawable="@drawable/ico2" />
</selector>
그리고 res/layout/activity_main.xml
:
<ImageButton
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/imageButton"
android:layout_gravity="center_horizontal"
android:onClick="eventImageBtn"
android:background="@drawable/btn_video"
android:adjustViewBounds="true"
android:scaleType="fitXY"
/>
클릭 한 번으로 이미지가 변경되고 선형 레이아웃으로 조정할 수 있습니다.
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/menu_item_background">
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"
android:paddingLeft="@dimen/main_screen_side_padding" android:paddingRight="@dimen/main_screen_side_padding" android:paddingTop="@dimen/main_screen_side_padding" android:paddingBottom="@dimen/main_screen_side_padding"
android:background="#ffb3ff13" android:weightSum="10.00">
<LinearLayout android:layout_weight="2.50" android:background="#ff56cfcd" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="0dp" >
<ImageButton
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/imageButton"
android:layout_gravity="center_horizontal"
android:onClick="eventImageBtn"
android:background="@drawable/btn_video"
android:adjustViewBounds="true"
android:scaleType="fitXY"
/>
</LinearLayout>
<LinearLayout android:layout_weight="0.50" android:layout_height="0dp" android:background="#ffffffff" android:orientation="vertical" android:layout_width="fill_parent" >
</LinearLayout>
<LinearLayout android:layout_weight="4.50" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="0dp" android:background="#ff8aa5ff">
</LinearLayout>
<LinearLayout android:layout_weight="0.50" android:layout_height="0dp" android:background="#ffffffff" android:orientation="vertical" android:layout_width="fill_parent" >
</LinearLayout>
<LinearLayout android:layout_weight="2.00" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="0dp" android:background="#ffff7d1a" >
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
내 솔루션은 " nineOldAndroids "라이브러리를 사용하여 이전 API도 지원합니다.
rootView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(final View v, final MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
v.setBackgroundResource(R.drawable.listview_normal);
ViewHelper.setAlpha(imageView, 1);
break;
case MotionEvent.ACTION_DOWN:
v.setBackgroundResource(0);
v.setBackgroundColor(getResources().getColor(R.color.listview_pressed));
ViewHelper.setAlpha(imageView, 0.75f);
break;
}
return false;
}
});
rootView가 셀 자체 (레이아웃)이고 전체 셀에 적용하려는 색상의 영향을 받고자하는 단일 imageView가 있다고 가정합니다.
편집 : 원하는 경우 ImageView를 확장하여 전경을 처리하고 "? android : attr / selectableItemBackground"로 설정할 수도 있습니다. 이것에 대한 라이브러리가 여기에 당신이 원하는보기 위해 작업을 수행하는 방법에 대한 자습서 여기가 .
이 스레드에 대한 도움을 주셔서 감사합니다. 그러나 한 가지를 놓쳤습니다. ACTION_CANCEL도 처리해야합니다. 그렇지 않으면 뷰 계층 구조의 상위 뷰가 터치 이벤트를 가로 챌 경우 ImageView의 알파 값을 제대로 복원하지 못할 수 있습니다 (ImageView를 래핑하는 ScrollView를 생각해보십시오).
다음은 위의 클래스를 기반으로하지만 ACTION_CANCEL도 처리하는 완전한 클래스입니다. ImageViewCompat 도우미 클래스를 사용하여 이전 JellyBean API의 차이점을 추상화합니다.
public class ChangeAlphaOnPressedTouchListener implements OnTouchListener {
private final float pressedAlpha;
public ChangeAlphaOnPressedTouchListener(float pressedAlpha) {
this.pressedAlpha = pressedAlpha;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
ImageView iv = (ImageView) v;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
ImageViewCompat.setAlpha(iv, pressedAlpha);
break;
case MotionEvent.ACTION_MOVE:
if (isInsideViewBounds(v, event)) {
ImageViewCompat.setAlpha(iv, pressedAlpha);
} else {
ImageViewCompat.setAlpha(iv, 1f);
}
break;
case MotionEvent.ACTION_UP:
ImageViewCompat.setAlpha(iv, 1f);
break;
case MotionEvent.ACTION_CANCEL:
ImageViewCompat.setAlpha(iv, 1f);
}
return false;
}
private static boolean isInsideViewBounds(View v, MotionEvent event) {
return event.getX() > 0 && event.getX() < v.getWidth() && event.getY() > 0
&& event.getY() < v.getHeight();
}
}
다음은 내 코드입니다. 사용자가 터치하면 ImageView가 컬러 필터를 얻고 사용자가 터치를 중지하면 컬러 필터가 제거된다는 아이디어입니다.
Martin Booka Weser, András, Ah Lam, altosh, 솔루션은 ImageView에도 onClickEvent가있는 경우 작동하지 않습니다. worawee.s 및 kcoppock (ImageButton 포함) 솔루션에는 배경이 필요하며 ImageView가 투명하지 않으면 의미가 없습니다.
이것은 컬러 필터에 대한 AZ_ 아이디어의 확장입니다 .
class PressedEffectStateListDrawable extends StateListDrawable {
private int selectionColor;
public PressedEffectStateListDrawable(Drawable drawable, int selectionColor) {
super();
this.selectionColor = selectionColor;
addState(new int[] { android.R.attr.state_pressed }, drawable);
addState(new int[] {}, drawable);
}
@Override
protected boolean onStateChange(int[] states) {
boolean isStatePressedInArray = false;
for (int state : states) {
if (state == android.R.attr.state_pressed) {
isStatePressedInArray = true;
}
}
if (isStatePressedInArray) {
super.setColorFilter(selectionColor, PorterDuff.Mode.MULTIPLY);
} else {
super.clearColorFilter();
}
return super.onStateChange(states);
}
@Override
public boolean isStateful() {
return true;
}
}
용법:
Drawable drawable = new FastBitmapDrawable(bm);
imageView.setImageDrawable(new PressedEffectStateListDrawable(drawable, 0xFF33b5e5));
나는 시도했다 :
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/get_started"
android:src="@drawable/home_started"
style="?android:borderlessButtonStyle"
android:adjustViewBounds="true"
android:clickable="true"
android:elevation="5dp"
android:longClickable="true" />
그리고 이것은 작동했습니다. 다음 라인에 유의하십시오.style="?android:borderlessButtonStyle"
가장 쉬운 방법은 새 XML 파일을 만드는 것입니다. 이 경우 드로어 블 폴더에서 "example.xml"이라고 부르고 다음 코드를 입력합니다.
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/blue"
android:state_pressed="true" />
</selector>
그러나 그 전에 다음과 같이 colors.xml 파일의 values 폴더에 색상을 설정해야합니다.
<resources>
<color name="blue">#0000FF</color>
</resources>
이제 다음과 같이 새 레이아웃을 사용하도록 Button / ImageButton을 설정했습니다.
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/example"
/>
그런 다음 해당 이미지를 클릭하면에 설정된 색상으로 변경됩니다.
<item android:drawable="@color/blue"
android:state_pressed="true" />
원하는 피드백 제공 ...
이것은 내가 본 최고의 솔루션입니다. 더 일반적입니다.
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true" >
<alpha
android:duration="100"
android:fromAlpha="0.0"
android:interpolator="@android:anim/accelerate_interpolator"
android:toAlpha="1.0" />
</set>
지금은 머티리얼 디자인 실습을 개발해야합니다 . 이 경우 ImageView에 파급 효과를 추가 할 수 있습니다.
XML 속성, android : clickable = "true"...를 추가하기 만하면됩니다.