android android-custom-view

Deslizar para elegir Android



android-custom-view (6)

Quiero hacer una vista como la de la siguiente imagen ... deslizar para elegir en ANDROID.

Encontré una biblioteca en github:

https://github.com/kikoso/Swipeable-Cards

http://grishma102.blogspot.in/2014/04/tinder-app-like-control-with-animation.html

pero en esta biblioteca no hay opción para mostrar la imagen LIKED o NOPE over CARD, como se muestra en la imagen de arriba

¿Puede alguien ayudarme a agregar estos futuros en esta biblioteca?

EDITADO 10-10-2014

He creado una clase de grupo de vistas dentro de la que he hecho onTouchListener

Estoy tratando de seguir onClickListener dentro de onTouchListener

mi problema es cuando estoy tocando en la esquina izquierda y derecha antes de hacer clic en el evento alguna vez su vista de rotación luego hacer clic es un trabajo, así que cómo lo detengo cuando el clic es un trabajo, otro problema es cuando la animación detiene su evento de hacer clic también

¿Alguien me ayudo a mejorar el siguiente código?

this.imageContainerLayout.setOnTouchListener(new OnTouchListener() { private long startClickTime; private float x1; private float y1; private float x2; private float y2; private float _dx; private float _dy; @Override public boolean onTouch(View v, MotionEvent event) { x_cord = (int) event.getRawX(); y_cord = (int) event.getRawY(); Log.e("start x_cord-->" + x_cord, "y_cord--->" + y_cord); boolean defaultResult = v.onTouchEvent(event); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: x = (int) event.getRawX(); y = (int) event.getRawY(); this.startClickTime = Calendar.getInstance() .getTimeInMillis(); x1 = event.getRawX(); y1 = event.getRawY(); return true; case MotionEvent.ACTION_MOVE: x_cord = (int) event.getRawX(); // Updated for more // smoother animation. y_cord = (int) event.getRawY(); Log.e("move x_cord-->" + x_cord, "y_cord--->" + y_cord); CardView_new.this.setX(event.getRawX() - x); CardView_new.this.setY(event.getRawY() - y); if (x_cord >= screenCenter) { /** * rotate image * */ CardView_new.this .setRotation((float) (0.02454369260617026D * (x_cord - screenCenter))); if (x_cord > (screenCenter + (screenCenter / 2))) { buttonLike.setAlpha(1); buttonDislike.setAlpha(0); if (x_cord > (windowwidth - (screenCenter / 4))) { Likes = 2; moveIs = true; } else { Likes = 0; moveIs = true; } } else { Likes = 0; buttonLike.setAlpha(0); moveIs = false; } buttonDislike.setAlpha(0); } else { // rotate /** * rotate image * */ CardView_new.this .setRotation((float) (0.02454369260617026D * (x_cord - screenCenter))); if (x_cord < (screenCenter / 2)) { buttonDislike.setAlpha(1); buttonLike.setAlpha(0); if (x_cord < (screenCenter / 4)) { Likes = 1; moveIs = true; } else { Likes = 0; moveIs = true; } } else { Likes = 0; buttonDislike.setAlpha(0); moveIs = false; } buttonLike.setAlpha(0); } return true; case MotionEvent.ACTION_UP: x_cord = (int) event.getRawX(); y_cord = (int) event.getRawY(); buttonDislike.setAlpha(0); buttonLike.setAlpha(0); x2 = event.getRawX(); y2 = event.getRawY(); _dx = x2 - x1; _dy = y2 - y1; long l = Calendar.getInstance().getTimeInMillis() - this.startClickTime; if ((l < 400L) && distance(x1, y1, x2, y2) < MAX_CLICK_DISTANCE) { Log.e("start Activity", "start activity"); CardView_new.this.setX(0); CardView_new.this.setY(0); CardView_new.this.setRotation(0); if (moveIs == false) { Intent i = new Intent((Activity) getContext(), DetailsActivity.class); ((Activity) getContext()).startActivity(i); } return true; } else if (Likes == 0) { CardView_new.this.setX(0); CardView_new.this.setY(0); CardView_new.this.setRotation(0); if (moveIs) { moveIs = true; return true; } else { moveIs = false; return false; } } else if (Likes == 1) { parentView.removeView(CardView_new.this); CardView_new.this.mOnCardDimissedDelegate .onLike(CardView_new.this); Log.e("Likes==1", "Likes==1"); moveIs = true; return true; } else if (Likes == 2) { parentView.removeView(CardView_new.this); CardView_new.this.mOnCardDimissedDelegate .onDislike(CardView_new.this); Log.e("Likes==2", "Likes==2"); moveIs = true; return true; } default: return false; } } });


Con la ayuda de la biblioteca de Swipecard , hice una interfaz de usuario como la animación de la tarjeta magnética de yesca.

Puede descargar el ejemplo here , donde expliqué paso a paso allí.


Cree cuatro nuevas variables flotantes globales x_cord, y_cord, x_cordIn & y_cordIn.

ainerLayout.setOnTouchListener(new OnTouchListener() { private long startClickTime; private float x1; private float y1; private float x2; private float y2; private float _dx; private float _dy; @Override public boolean onTouch(View v, MotionEvent event) { boolean defaultResult = v.onTouchEvent(event); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: x_cord = x_cordIn = event.getRawX(); y_cord = y_cordIn = event.getRawY(); x1 = (int) event.getRawX(); y1 = (int) event.getRawY(); this.startClickTime = Calendar.getInstance().getTimeInMillis(); return true; case MotionEvent.ACTION_MOVE: x_cord = event.getRawX(); y_cord = event.getRawY(); float xPos = myRelView.getX() - (x_cordIn - x_cord); float yPos = myRelView.getY() - (y_cordIn - y_cord); CardView_new.this.setX(xPos); CardView_new.this.setY(yPos); if (x_cord >= screenCenter) { /** * rotate image * */ CardView_new.this.setRotation((float) (xPos * (Math.PI / 32))); if (x_cord > (screenCenter + (screenCenter / 2))) { buttonLike.setAlpha(1); buttonDislike.setAlpha(0); if (x_cord > (windowwidth - (screenCenter / 4))) { Likes = 2; moveIs = true; } else { Likes = 0; moveIs = true; } } else { Likes = 0; buttonLike.setAlpha(0); moveIs = false; } buttonDislike.setAlpha(0); } else { // rotate /** * rotate image * */ CardView_new.this.setRotation((float) (xPos * (Math.PI / 32))); if (x_cord < (screenCenter / 2)) { buttonDislike.setAlpha(1); buttonLike.setAlpha(0); if (x_cord < (screenCenter / 4)) { Likes = 1; moveIs = true; } else { Likes = 0; moveIs = true; } } else { Likes = 0; buttonDislike.setAlpha(0); moveIs = false; } buttonLike.setAlpha(0); } return true; case MotionEvent.ACTION_UP: x_cord = (int) event.getRawX(); y_cord = (int) event.getRawY(); buttonDislike.setAlpha(0); buttonLike.setAlpha(0); x2 = event.getRawX(); y2 = event.getRawY(); _dx = x2 - x1; _dy = y2 - y1; long l = Calendar.getInstance().getTimeInMillis() - this.startClickTime; if ((l < 400L) && distance(x1, y1, x2, y2) < MAX_CLICK_DISTANCE) { Log.e("start Activity", "start activity"); CardView_new.this.setX(0); CardView_new.this.setY(0); CardView_new.this.setRotation(0); if (moveIs == false) { Intent i = new Intent((Activity) getContext(), DetailsActivity.class); ((Activity) getContext()).startActivity(i); } return true; } else if (Likes == 0) { CardView_new.this.setX(0); CardView_new.this.setY(0); CardView_new.this.setRotation(0); if (moveIs) { moveIs = true; return true; } else { moveIs = false; return false; } } else if (Likes == 1) { parentView.removeView(CardView_new.this); CardView_new.this.mOnCardDimissedDelegate .onLike(CardView_new.this); Log.e("Likes==1", "Likes==1"); moveIs = true; return true; } else if (Likes == 2) { parentView.removeView(CardView_new.this); CardView_new.this.mOnCardDimissedDelegate .onDislike(CardView_new.this); Log.e("Likes==2", "Likes==2"); moveIs = true; return true; } default: return false; } } });


He usado esta biblioteca: https://github.com/kikoso/Swipeable-Cards

Necesitas modificarlo. Después de las modificaciones, lo lograrás (ver capturas de pantalla a continuación). Dejame explicar.

1.) std_card_inner.xml

Este xml se usa para inflar la fila de la tarjeta en la clase de adaptador de la biblioteca. Lo modifiqué para agregar dos vistas de imagen que contienen el botón Me gusta y no me gusta y una vista de texto para mostrar el texto "Me gusta" o "No me gusta" cuando el usuario hace clic en cualquier vista de imagen.

<RelativeLayout android:id="@+id/inner_relative" android:layout_width="wrap_content" android:layout_height="wrap_content" > <TextView android:id="@+id/title" style="@android:style/TextAppearance.Large.Inverse" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@color/card_bg" android:padding="10dp" android:textColor="@android:color/primary_text_light" android:textSize="24sp" android:textStyle="bold" tools:text="Title" /> <View android:id="@+id/divider_title" android:layout_width="fill_parent" android:layout_height="2dp" android:layout_below="@id/title" android:background="@color/card_outline" /> <ImageView android:id="@+id/image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignWithParentIfMissing="true" android:layout_below="@id/divider_title" android:scaleType="centerCrop" tools:src="@drawable/picture1" /> <View android:id="@+id/divider_bottom" android:layout_width="fill_parent" android:layout_height="2dp" android:layout_below="@id/image" android:background="@color/card_outline" /> <View android:layout_width="fill_parent" android:layout_height="10dp" android:layout_alignBottom="@+id/image_1" android:layout_below="@+id/divider_bottom" android:background="@color/card_bg" /> <TextView android:id="@+id/description" style="@android:style/TextAppearance.Inverse" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/image_2" android:layout_alignParentLeft="true" android:layout_below="@id/image" android:layout_toLeftOf="@+id/btn_sep_1" android:ellipsize="end" android:fontFamily="sans-serif-condensed" android:gravity="center_vertical" android:lines="1" android:padding="10dp" android:textColor="@android:color/secondary_text_light" tools:text="This is the description, it is a long description, as you can see" /> <View android:id="@+id/btn_sep_1" android:layout_width="1dp" android:layout_height="0dp" android:layout_alignBottom="@+id/image_1" android:layout_below="@id/image" android:layout_marginTop="7dp" android:layout_toLeftOf="@+id/image_1" android:background="#ccc" /> <ImageButton android:id="@+id/image_1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/image" android:layout_toLeftOf="@+id/btn_sep_2" android:background="?android:attr/selectableItemBackground" android:padding="10dp" android:src="@drawable/camera" /> <View android:id="@+id/btn_sep_2" android:layout_width="1dp" android:layout_height="0dp" android:layout_alignBottom="@id/image_1" android:layout_below="@id/image" android:layout_marginTop="7dp" android:layout_toLeftOf="@+id/image_2" android:background="#ccc" /> <ImageButton android:id="@+id/image_2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_below="@id/image" android:background="?android:attr/selectableItemBackground" android:padding="10dp" android:src="@drawable/people" /> </RelativeLayout> <LinearLayout android:id="@+id/like_dislike" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/inner_relative" android:background="@android:color/white" android:gravity="center" android:orientation="horizontal" android:padding="10dp" > <ImageView android:id="@+id/like" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginRight="10dp" android:src="@drawable/ic_like" /> <ImageView android:id="@+id/dislike" android:layout_width="50dp" android:layout_height="50dp" android:layout_marginLeft="10dp" android:src="@drawable/ic_dislike" /> </LinearLayout> <TextView android:id="@+id/like_dislike_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/like_dislike" android:background="#fff" android:gravity="center" android:textColor="#000000" /> </RelativeLayout>

2.) SimpleCardStackAdapter.java

Este es el adaptador para las tarjetas. Lo modifiqué para agregar los escuchas de clics para me gusta y no me gusta la vista de imagen y una vista de texto para mostrar el texto. Cuando el usuario hace clic en el botón "Me gusta", he agregado una variable booleana en el modelo de tarjeta que almacena el valor de "me gusta / no me gusta". Cierto para gustar y falso para disgusto.

package com.andtinder.view; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import com.andtinder.R; import com.andtinder.model.CardModel; public final class SimpleCardStackAdapter extends CardStackAdapter { public SimpleCardStackAdapter(Context mContext) { super(mContext); } @Override public View getCardView(int position, final CardModel model, View convertView, ViewGroup parent) { if(convertView == null) { LayoutInflater inflater = LayoutInflater.from(getContext()); convertView = inflater.inflate(R.layout.std_card_inner, parent, false); assert convertView != null; } ((ImageView) convertView.findViewById(R.id.image)).setImageDrawable(model.getCardImageDrawable()); ((TextView) convertView.findViewById(R.id.title)).setText(model.getTitle()); ((TextView) convertView.findViewById(R.id.description)).setText(model.getDescription()); final TextView like_dislike_text = ((TextView) convertView.findViewById(R.id.like_dislike_text)); if(model.isLike()) like_dislike_text.setText("Liked"); else like_dislike_text.setText("DisLiked"); ((ImageView) convertView.findViewById(R.id.like)).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub model.setLike(true); like_dislike_text.setText("Liked"); } }); ((ImageView) convertView.findViewById(R.id.dislike)).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub model.setLike(false); like_dislike_text.setText("DisLiked"); } }); return convertView; } }

3.) CardModel.java

Finalmente, aquí he agregado esa variable booleana que almacena el valor para me gusta / no me gusta.

private boolean isLike = false; public boolean isLike() { return isLike; } public void setLike(boolean isLike) { this.isLike = isLike; }

Este es el resultado final:

Captura de pantalla 1

Captura de pantalla 2


Obtuve un resultado para el botón Me gusta y a diferencia de voltear las imágenes hacia la izquierda y la derecha .

Utilice estas here .

MainActivity.java:

Dentro del MyAppAdapter getView() , agregue los siguientes códigos:

viewHolder.likeImg.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Toast.makeText(getApplicationContext(), "click", Toast.LENGTH_SHORT).show(); flipMethodRight(80.00f); } }); viewHolder.unlikeImg.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Toast.makeText(getApplicationContext(), "click", Toast.LENGTH_SHORT).show(); flipMethodLeft(-80.00f); } });

Agregue estos códigos a continuación fuera de la MyAppAdapter class :

void flipMethodRight(float scrollProgressPercent) { flingContainer.getTopCardListener().selectRight(); View view = flingContainer.getSelectedView(); view.findViewById(R.id.background).setAlpha(0); view.findViewById(R.id.item_swipe_left_indicator).setAlpha(scrollProgressPercent > 0 ? scrollProgressPercent : 0); } void flipMethodLeft(float scrollProgressPercent) { flingContainer.getTopCardListener().selectLeft(); View view = flingContainer.getSelectedView(); view.findViewById(R.id.background).setAlpha(0); view.findViewById(R.id.item_swipe_right_indicator).setAlpha(scrollProgressPercent < 0 ? -scrollProgressPercent : 0); }

Gracias a @nirav kalola por esta muestra.



Use un viewpager y cambie el OnPageChangeListener.

http://developer.android.com/reference/android/support/v4/view/ViewPager.OnPageChangeListener.html

Simplemente sobrecargue el método onPageScrolled (int position, float positionOffset, int positionOffsetPixels). El int está relacionado con el índice del elemento en el adaptador, por lo que puede usarlo para identificar la imagen.

Ejemplo:

_viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int i, float v, int i2) { System.out.println("SWIPING!!!!"); } @Override public void onPageSelected(int i) { System.out.println("SELECTED!!!!"); } @Override public void onPageScrollStateChanged(int i) { System.out.println("CHANGED!!!!"); } });