У моєму додатку для Android у мене є програма перегляду зображень, яку я використовую як кнопку із вказаною подією onClick, але, як ви вже здогадуєтесь, вона не надає перегляду зображень ефект, який можна натиснути. Як я можу цього досягти?
У моєму додатку для Android у мене є програма перегляду зображень, яку я використовую як кнопку із вказаною подією onClick, але, як ви вже здогадуєтесь, вона не надає перегляду зображень ефект, який можна натиснути. Як я можу цього досягти?
Відповіді:
Ви можете розробляти різні зображення для стану натискання / не натискання та встановлювати їх у 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 ...>
а потім встановити ImageView, який можна натискати в XML, як<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 (або ImageButton, оскільки це також підклас ImageView) для полегшення повторного використання, але це повинно дозволити вам застосувати "вибраний" вигляд до зображення.
false
, інакше фактична onClick()
подія вигляду не буде запущена
За допомогою методу ColorFilter можна обійтися лише одним файлом зображення . Однак ColorFilter розраховує працювати з ImageViews, а не з кнопками, тому вам доведеться перетворити ваші кнопки в ImageViews. Це не проблема, якщо ви в будь-якому випадку використовуєте зображення як кнопки, але це дратує, якщо у вас є текст ... У будь-якому випадку, якщо ви знайдете спосіб вирішити проблему з текстом, ось код для використання:
ImageView button = (ImageView) findViewById(R.id.button);
button.setColorFilter(0xFFFF0000, PorterDuff.Mode.MULTIPLY);
Це стосується кнопки червоного накладання (кольоровий код - це шістнадцятковий код для повністю непрозорого червоного - спочатку дві цифри є прозорістю, потім це RR GG BB.).
РЕДАГУВАТИ : Хоча оригінальна відповідь нижче працює і її легко налаштувати, зверніться до цієї публікації адвоката розробника Android у Google, якщо ви хочете / потребуєте більш ефективного впровадження. Також зауважте, що android:foreground
атрибут за замовчуванням доступний до всіх подань, включаючи ImageView, в Android M.
Проблема використання селектора для ImageView полягає в тому, що ви можете встановити його лише як фон перегляду - поки ваше зображення непрозоре, ви не побачите ефекту селектора за ним.
Фокус полягає в тому, щоб обернути ваш ImageView у FrameLayout атрибутом, android:foreground
який дозволяє нам визначити накладання для його вмісту. Якщо ми встановимо android:foreground
на селектор (наприклад, ?android:attr/selectableItemBackground
для рівня API 11+) і прикріпимо його OnClickListener
до FrameLayout замість ImageView, зображення буде накладено на наш селектор, який можна малювати - ефект кліку, який ми бажаємо!
Ось:
<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 .
<ImageButton>
допомогою selectableItemBackground!
Використовуйте style = "? Android: 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_pressed замість android: state_selected
<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>
Ви можете спробувати android:background="@android:drawable/list_selector_background"
отримати такий самий ефект, як "Додати будильник" у типовому "Будильнику" (тепер Настільний годинник).
Якщо вам потрібно пульсація при натисканні, це може бути подано за допомогою цього коду:
<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: Як сказав Гунхан, із методом 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;
}
});
У мене встановлено onClickListener на imageView, але це може бути методом.
MotionEvent.ACTION_CANCEL
з тією ж функціональністю, що і MotionEvent.ACTION_UP
тоді, можна "очистити" подання, якщо користувачі виконують "перетягування", яке не є дією клацання.
Ви можете setPressed
замінити в ImageView і зробити там фільтрацію кольорів, замість того, щоб створювати слухачі onTouchEvent:
@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();
}
}
На основі відповіді пана Цорна , я використовую статичний метод у своєму абстрактному класі Utility:
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)
Це дуже просто, якщо у вас багато зображень, і ви хочете отримати простий ефект onTouch, без будь-якого XML, що малюється, і лише одного зображення.
Використовуйте android.widget.Button
та встановіть для його background
властивості значення android.graphics.drawable.StateListDrawable
. Це все можна зробити у форматі XML або програмно. Дивіться розділ " Спеціальна кнопка" підручника "Форма" .
Я створюю зразок тут , просто змініть ImageView в ClickableImageView від макета. Сподіваюся, це допоможе.
Я думаю, що ImageButton є кращим рішенням
<ImageButton
android:layout_width="96dp"
android:layout_height="56dp"
android:src="@mipmap/ic_launcher"
android:adjustViewBounds="true"
android:background="@android:color/transparent"
android:foreground="@drawable/selector" />
У мене є більш красиве рішення, якщо ви використовуєте фонові зображення :)
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, якщо батьківський подання в ієрархії подання перехоплює подію дотику (думайте, ScrollView обгортає вас ImageView).
Ось повний клас, який базується на вищевказаному класі, але також піклується про ACTION_CANCEL. Він використовує допоміжний клас ImageViewCompat, щоб абстрагувати відмінності в API до JellyBean до публікації.
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, у папці значень, наприклад:
<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>
Я зробив наступне в XML - з 0 відступами навколо зображення та пульсацією зверху зображення:
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@drawable/my_image"
android:clickable="true"
android:focusable="true"
android:src="?android:attr/selectableItemBackground" />
Наразі нам слід розвивати практику матеріального дизайну . У цьому випадку ви можете додати ефект пульсації на ImageView.
Просто додайте атрибут XML, android: clickable = "true" ...