Obtener el elemento visible en el centro de RecycleView al desplazarse

Esto es lo que quiero:

Introduzca aquí la descripción de la imagen

Como la imagen de arriba, quiero dibujar una línea central en RecycleView , a continuación, obtener el elemento central al desplazarse (así como mover a la izquierda o derecha)
Aquí está mi intento para dibujar un RecycleView horizontal:

  HorizontalAdapter adapter = new HorizontalAdapter(data); LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false); recycleView.setLayoutManager(layoutManager); recycleView.setAdapter(adapter); 

¿Hay alguna forma de saber qué elemento se traslada al centro de RecycleView ? ¿Y cómo puedo desplazar RecycleView a izquierda o derecha sólo una posición?

Actualización : He intentado usar un oyente de desplazamiento para obtener la posición media, pero no funciona como aspecto.

  @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); int firstPos = layoutManager.findFirstVisibleItemPosition(); int lastPos = layoutManager.findLastVisibleItemPosition(); int middle = Math.abs(lastPos - firstPos) / 2 + firstPos; int selectedPos = -1; for (int i = 0; i < adapter.getItemCount(); i++) { if (i == middle) { adapter.getItem(i).setSelected(true); selectedPos = i; } else { adapter.getItem(i).setSelected(false); } } adapter.notifyDataSetChanged(); } 

Y obtener el resultado:

Introduzca aquí la descripción de la imagen

Sólo quiero cambiar el elemento de selección (hacer texto a color blanco) cuando está en el Rect azul

Hice algo como esto. Puedo hacer exactamente lo que necesitas. En primer lugar, esto es cómo es mi trabajo de alogrítimo Introduzca aquí la descripción de la imagen

Este es mi adaptador recyclerView

 public class DateAdapter extends RecyclerView.Adapter<DateAdapter.DateViewHolder> { private ArrayList<LabelerDate> dateDataList; private static final int VIEW_TYPE_PADDING = 1; private static final int VIEW_TYPE_ITEM = 2; private int paddingWidthDate = 0; private int selectedItem = -1; public DateAdapter(ArrayList<LabelerDate> dateData, int paddingWidthDate) { this.dateDataList = dateData; this.paddingWidthDate = paddingWidthDate; } @Override public DateViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == VIEW_TYPE_ITEM) { final View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_date, parent, false); return new DateViewHolder(view); } else { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_padding, parent, false); RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) view.getLayoutParams(); layoutParams.width = paddingWidthDate; view.setLayoutParams(layoutParams); return new DateViewHolder(view); } } @Override public void onBindViewHolder(DateViewHolder holder, int position) { LabelerDate labelerDate = dateDataList.get(position); if (getItemViewType(position) == VIEW_TYPE_ITEM) { if(labelerDate.dateType.equals(BirthDayActivity.DateType.C31)) holder.tvDate.setText(String.valueOf(labelerDate.valueDate)); holder.tvDate.setVisibility(View.VISIBLE); holder.imgSmall.setVisibility(View.VISIBLE); if (position == selectedItem) { holder.tvDate.setTextColor(Color.parseColor("#094673")); holder.tvDate.setTextSize(35); holder.imgSmall.setBackgroundResource(R.color.textviewbold); } else { holder.tvDate.setTextColor(Color.GRAY); holder.tvDate.setTextSize(35); holder.imgSmall.setBackgroundResource(R.color.gray); } } } public void setSelecteditem(int selecteditem) { this.selectedItem = selecteditem; notifyDataSetChanged(); } @Override public int getItemCount() { return dateDataList.size(); } @Override public int getItemViewType(int position) { LabelerDate labelerDate = dateDataList.get(position); if (labelerDate.dateType.equals(BirthDayActivity.DateType.NONE)) { return VIEW_TYPE_PADDING; } return VIEW_TYPE_ITEM; } public class DateViewHolder extends RecyclerView.ViewHolder { public TextView tvDate; public ImageView imgSmall; public DateViewHolder(View itemView) { super(itemView); tvDate = (TextView) itemView.findViewById(R.id.tvNumberDate); imgSmall = (ImageView) itemView.findViewById(R.id.small_marked_dob); } }} 

Este es el alogrítimo más importante:

 public void getRecyclerviewDate() { recyclerViewDate = (RecyclerView) findViewById(R.id.recyclerViewDay); ViewTreeObserver vtoDate = recyclerViewDate.getViewTreeObserver(); vtoDate.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { recyclerViewDate.getViewTreeObserver().removeOnPreDrawListener(this); finalWidthDate = recyclerViewDate.getMeasuredWidth(); itemWidthDate = getResources().getDimension(R.dimen.item_dob_width); paddingDate = (finalWidthDate - itemWidthDate) / 2; firstItemWidthDate = paddingDate ; allPixelsDate = 0; final LinearLayoutManager dateLayoutManager = new LinearLayoutManager(getApplicationContext()); dateLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); recyclerViewDate.setLayoutManager(dateLayoutManager); recyclerViewDate.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); synchronized (this) { if(newState == RecyclerView.SCROLL_STATE_IDLE){ calculatePositionAndScrollDate(recyclerView); } } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); allPixelsDate += dx; } }); if (labelerDates == null) labelerDates = new ArrayList<>(); labelerDates.addAll(genLabelerDate(currentMonth, currentYear)); dateAdapter = new DateAdapter(labelerDates, (int) firstItemWidthDate); recyclerViewDate.setAdapter(dateAdapter); return true; } }); } /* this if most important, if expectedPositionDate < 0 recyclerView will return to nearest item*/ private void calculatePositionAndScrollDate(RecyclerView recyclerView) { int expectedPositionDate = Math.round((allPixelsDate + paddingDate - firstItemWidthDate) / itemWidthDate); if (expectedPositionDate == -1) { expectedPositionDate = 0; } else if (expectedPositionDate >= recyclerView.getAdapter().getItemCount() - 2) { expectedPositionDate--; } scrollListToPositionDate(recyclerView, expectedPositionDate); } /* this if most important, if expectedPositionDate < 0 recyclerView will return to nearest item*/ private void scrollListToPositionDate(RecyclerView recyclerView, int expectedPositionDate) { float targetScrollPosDate = expectedPositionDate * itemWidthDate + firstItemWidthDate - paddingDate; float missingPxDate = targetScrollPosDate - allPixelsDate; if (missingPxDate != 0) { recyclerView.smoothScrollBy((int) missingPxDate, 0); } } private void setDateValue() { int expectedPositionDateColor = Math.round((allPixelsDate + paddingDate - firstItemWidthDate) / itemWidthDate); setColorDate = expectedPositionDateColor + 1; //set color here dateAdapter.setSelecteditem(setColorDate); } @Override protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); allPixelsDate = savedInstanceState.getFloat(BUNDLE_LIST_PIXELS_DATE); allPixelsDateChanged = savedInstanceState.getFloat(BUNDLE_LIST_PIXELS_DATE_CHANGED); } @Override protected void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); outState.putFloat(BUNDLE_LIST_PIXELS_DATE, allPixelsDate); outState.putFloat(BUNDLE_LIST_PIXELS_DATE_CHANGED, allPixelsDateChanged); } 

Y este es mi resultado: Introduzca aquí la descripción de la imagen

Mira este enlace de video, esta es mi demo de aplicación

A veces se necesita el bloque de código de ejemplo completo juntos, porque podemos perder algo. Aquí es lo que tengo, siéntase libre de corregir cualquier cosa, ya que puede estar haciendo algún pequeño error en alguna parte. Y Sí, esta respuesta es una extensión de la respuesta @tranhieu. Gracias @tranhieu.

MainActivity.java

 package com.test; import android.app.Activity; import android.graphics.Color; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.widget.TextView; import java.util.ArrayList; public class MainActivity extends Activity { private static final String TAG = MainActivity.class.getSimpleName(); public float firstItemWidthDate; public float paddingDate; public float itemWidthDate; public int allPixelsDate; public int finalWidthDate; private DateAdapter dateAdapter; private ArrayList<LabelerDate> labelerDates = new ArrayList<>(); @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getRecyclerviewDate(); } public void getRecyclerviewDate() { final RecyclerView recyclerViewDate = (RecyclerView) findViewById(R.id.rv_tasks_date); if (recyclerViewDate != null) { recyclerViewDate.postDelayed(new Runnable() { @Override public void run() { setDateValue(); } }, 300); recyclerViewDate.postDelayed(new Runnable() { @Override public void run() { recyclerViewDate.smoothScrollToPosition(dateAdapter.getItemCount()-1); setDateValue(); } }, 5000); } ViewTreeObserver vtoDate = recyclerViewDate.getViewTreeObserver(); vtoDate.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { recyclerViewDate.getViewTreeObserver().removeOnPreDrawListener(this); finalWidthDate = recyclerViewDate.getMeasuredWidth(); itemWidthDate = getResources().getDimension(R.dimen.item_dob_width); paddingDate = (finalWidthDate - itemWidthDate) / 2; firstItemWidthDate = paddingDate; allPixelsDate = 0; final LinearLayoutManager dateLayoutManager = new LinearLayoutManager(getApplicationContext()); dateLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); recyclerViewDate.setLayoutManager(dateLayoutManager); recyclerViewDate.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); synchronized (this) { if (newState == RecyclerView.SCROLL_STATE_IDLE) { calculatePositionAndScrollDate(recyclerView); } } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); allPixelsDate += dx; } }); if (labelerDates == null) { labelerDates = new ArrayList<>(); } genLabelerDate(); dateAdapter = new DateAdapter(labelerDates, (int) firstItemWidthDate); recyclerViewDate.setAdapter(dateAdapter); dateAdapter.setSelecteditem(dateAdapter.getItemCount() - 1); return true; } }); } private void genLabelerDate() { for (int i = 0; i < 32; i++) { LabelerDate labelerDate = new LabelerDate(); labelerDate.setNumber(Integer.toString(i)); labelerDates.add(labelerDate); if (i == 0 || i == 31) { labelerDate.setType(DateAdapter.VIEW_TYPE_PADDING); } else { labelerDate.setType(DateAdapter.VIEW_TYPE_ITEM); } } } /* this if most important, if expectedPositionDate < 0 recyclerView will return to nearest item*/ private void calculatePositionAndScrollDate(RecyclerView recyclerView) { int expectedPositionDate = Math.round((allPixelsDate + paddingDate - firstItemWidthDate) / itemWidthDate); if (expectedPositionDate == -1) { expectedPositionDate = 0; } else if (expectedPositionDate >= recyclerView.getAdapter().getItemCount() - 2) { expectedPositionDate--; } scrollListToPositionDate(recyclerView, expectedPositionDate); } /* this if most important, if expectedPositionDate < 0 recyclerView will return to nearest item*/ private void scrollListToPositionDate(RecyclerView recyclerView, int expectedPositionDate) { float targetScrollPosDate = expectedPositionDate * itemWidthDate + firstItemWidthDate - paddingDate; float missingPxDate = targetScrollPosDate - allPixelsDate; if (missingPxDate != 0) { recyclerView.smoothScrollBy((int) missingPxDate, 0); } setDateValue(); } // private void setDateValue() { int expectedPositionDateColor = Math.round((allPixelsDate + paddingDate - firstItemWidthDate) / itemWidthDate); int setColorDate = expectedPositionDateColor + 1; // set color here dateAdapter.setSelecteditem(setColorDate); } public class DateAdapter extends RecyclerView.Adapter<DateAdapter.DateViewHolder> { private ArrayList<LabelerDate> dateDataList; private static final int VIEW_TYPE_PADDING = 1; private static final int VIEW_TYPE_ITEM = 2; private int paddingWidthDate = 0; private int selectedItem = -1; public DateAdapter(ArrayList<LabelerDate> dateData, int paddingWidthDate) { this.dateDataList = dateData; this.paddingWidthDate = paddingWidthDate; } @Override public DateViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == VIEW_TYPE_ITEM) { final View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false); return new DateViewHolder(view); } else { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false); RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) view.getLayoutParams(); layoutParams.width = paddingWidthDate; view.setLayoutParams(layoutParams); return new DateViewHolder(view); } } @Override public void onBindViewHolder(DateViewHolder holder, int position) { LabelerDate labelerDate = dateDataList.get(position); if (getItemViewType(position) == VIEW_TYPE_ITEM) { holder.tvDate.setText(labelerDate.getNumber()); holder.tvDate.setVisibility(View.VISIBLE); Log.d(TAG, "default " + position + ", selected " + selectedItem); if (position == selectedItem) { Log.d(TAG, "center" + position); holder.tvDate.setTextColor(Color.parseColor("#76FF03")); holder.tvDate.setTextSize(35); } else { holder.tvDate.setTextColor(Color.WHITE); holder.tvDate.setTextSize(18); } } else { holder.tvDate.setVisibility(View.INVISIBLE); } } public void setSelecteditem(int selecteditem) { this.selectedItem = selecteditem; notifyDataSetChanged(); } @Override public int getItemCount() { return dateDataList.size(); } @Override public int getItemViewType(int position) { LabelerDate labelerDate = dateDataList.get(position); if (labelerDate.getType() == VIEW_TYPE_PADDING) { return VIEW_TYPE_PADDING; } else { return VIEW_TYPE_ITEM; } } public class DateViewHolder extends RecyclerView.ViewHolder { public TextView tvDate; public DateViewHolder(View itemView) { super(itemView); tvDate = (TextView) itemView.findViewById(R.id.txt_date); } } } private class LabelerDate { private int type; private String number; public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } public int getType() { return type; } public void setType(int type) { this.type = type; } } } 

Activity_main.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.v7.widget.RecyclerView android:id="@+id/rv_tasks_date" android:layout_width="match_parent" android:layout_height="48dp" /> <ImageView android:layout_width="48dp" android:layout_height="48dp" android:layout_gravity="center" android:layout_marginTop="48dp" android:src="@android:drawable/ic_dialog_info" /> </FrameLayout> </LinearLayout> 

Item.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="match_parent"> <TextView android:id="@+id/txt_date" android:layout_width="@dimen/item_dob_width" android:layout_height="48dp" android:text="32" android:textColor="@android:color/white" android:background="@android:color/darker_gray" android:textSize="28sp" android:gravity="center"/> </LinearLayout> 

Dimens.xml

 <resources> <dimen name="item_dob_width">100dp</dimen> </resources> 

Estoy usando el SnapHelper aquí:

  // init snaphelper SnapHelper snapHelper = new LinearSnapHelper(); snapHelper.attachToRecyclerView(recyclerView) // init layout manager LinearLayoutManager layoutManager = new LinearLayoutManager(mainActivity); layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); recyclerView.setLayoutManager(layoutManager); // init adapter adatper.setSnapHelper(snapHelper); adatper.setLayoutManager(layoutManager); adatper.initAdapter(new Float((DisplayHelper.getDisplayWidth(mainActivity) / 2) - (fooViewWidth / 2)).intValue()); recyclerView.setAdapter(adatper); 

Como dijo TranHieu la solución de insertar 2 elementos para relleno (en el inicio y en las posiciones finales) es buena.

No me gusta el uso de ViewTreeObserver debido a la escasa legibilidad del código. Con esta técnica, también debe administrar el redibujo de los elementos si se reciclan.

Si está utilizando clases de vista personalizada, puede establecer su ancho directamente en estas clases.

Por ejemplo, esta es mi clase de relleno

 /** * Created by firegloves on 25/09/15. */ @EViewGroup(R.layout.view_padding) public class PaddingView extends FooView { Context mCtx; public PaddingView(Context context) { super(context); mCtx = context; } public void setWidth(int width) { setLayoutParams(new LayoutParams(width, ViewGroup.LayoutParams.WRAP_CONTENT)); } } 

En mi adaptador almaceno el ancho deseado del elemento de relleno, que es igual a (displayWidth / 2) – (realItemWidth / 2)

Este es mi adaptador, no mire los métodos que no coinciden con RecyclerView.Adapter, preste atención al método initAdapter y al método onCreateItemView

 @EBean public class FooAdapterRecycler extends RecyclerViewAdapterBase<Foo, FooView> { private final int TYPE_PADDING_VIEW = 0; private final int TYPE_REAL_VIEW = 1; @RootContext Context ctx; @Bean(Finder.class) IFinder finder; SnapHelper snapHelper; RecyclerView.LayoutManager layoutManager; private int paddingWidth = 0; /** * preleva i dati dal finder */ public void initAdapter(int paddingWidth) { /******************************* * THIS CODE IS THE IMPORTANT ONE ******************************/ this.paddingWidth = paddingWidth; // add 1 item for initial space mItems = new ArrayList<>(); Foo foo = new Foo(); mItems.add(foo); // get real items from finder mItems.addAll(finder.findAll()); // add 1 item for final space mItems = new ArrayList<>(); Foo foo2 = new Foo(); mItems.add(foo2); } @Override public int getItemViewType(int position) { if (position == 0 || position == getItemCount()-1) { return TYPE_PADDING_VIEW; } else { return TYPE_REAL_VIEW; } } @Override protected FooView onCreateItemView(ViewGroup parent, int viewType) { /******************************* * THIS CODE IS THE IMPORTANT ONE ******************************/ if (viewType == TYPE_PADDING_VIEW) { PaddingView view = PaddingView_.build(ctx); view.setWidth(paddingWidth); return view; } else { return FooView_.build(ctx); } } public void setSnapHelper(SnapHelper snapHelper) { this.snapHelper = snapHelper; } public void setLayoutManager(RecyclerView.LayoutManager layoutManager) { this.layoutManager = layoutManager; } } 

Estoy utilizando la biblioteca AndroidAnnotations pero no es necesario

Espero que ayude

Como se mencionó en la otra respuesta, no hay forma directa de hacerlo.

Esta es probablemente la forma en que puede lograr lo que describió en la pregunta.

  1. Conozca el número de elementos visibles en la pantalla.
  2. Seleccione el elemento central de forma programática cada vez que se despliegue la vista.
  3. Mantenga una imagen parcialmente transparente como una superposición en el elemento central de la vista de reciclaje. (Deberá calcular las coordenadas según el ancho de la vista del reciclador o el ancho de la pantalla y el ancho de la imagen de superposición que elija colocar.
  4. Actualiza el valor seleccionado en una vista de texto debajo de la vista del reciclador cada vez que hay un desplazamiento.

Las superposiciones de imágenes tienen que colocarse de manera que aparezcan conectadas y como un solo control.

Para esta función, use la biblioteca de EcoGallery: https://github.com/falnatsheh/EcoGallery

No creo que haya un enfoque directo para lograr esto. Usted puede intentar esto –

ListView.setOnScrollListener (escucha);

@Anular

 public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) { int firstVisibleRow = listView.getFirstVisiblePosition(); int lastVisibleRow = listView.getLastVisiblePosition(); int count - ((int*)count/2; int middle = listview.getChildAt(count - ((int)count/2)); } } 

Puede referir esta respuesta también https://stackoverflow.com/a/13134100/1320616 https://stackoverflow.com/a/19205940/1320616

Al principio, necesitaba algo similar, no esto. Pero pude adaptar la solución @TranHieu a mis necesidades, así que voté por su solución.

Quise crear el recyclerview horizontal de la plena pantalla que después de que el usuario sroll mueva scrollPosition a mostVisibleItem.

preparar:

 private void setUpScrolling() { mRecyclerVIew.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { mRecyclerVIew.getViewTreeObserver().removeOnPreDrawListener(this); CustomScrollListener listener = (CustomScrollListener) mScrollListener; listener.width = mRecyclerVIew.getMeasuredWidth(); listener.dx = 0; return true; } }); } 

oyente:

 private class CustomScrollListener extends OnScrollListener { private int mLastDx = 0; int width = 0; int dx = 0; @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { if (newState == RecyclerView.SCROLL_STATE_IDLE) { if (mLastDx != dx) { scrollToMostVisibleItem(); } else { dx = 0; mLastDx = 0; } } super.onScrollStateChanged(recyclerView, newState); } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); this.dx += dx; } private void scrollToMostVisibleItem() { int direction = (dx > 0) ? 1 : -1; dx = Math.abs(dx); int shiftCount = Math.round(dx / width); int pixelShift = dx % width; if (pixelShift > width / 2) { shiftCount++; } float targetScrollPixels = shiftCount * width; float finalScrollPixels = (targetScrollPixels - dx) * direction; if (finalScrollPixels != 0) { mRecyclerVIew.smoothScrollBy((int) finalScrollPixels, 0); mLastDx = (int) finalScrollPixels; dx = 0; } } } 

Utilicé otro enfoque en mi caso.

Usted puede encontrar los deatils aquí: RecyclerView – cómo resaltar elemento visible central durante el desplazamiento 1

En mi opinión, mi solución es más fácil que las otras.

  • Android ListView actual ubicación de desplazamiento Y píxeles
  • Android lista ver espacio extra al final cuando se desplaza
  • Android smoothScrollBy se comporta mal
  • Scrollview no desliza cuando es demasiado corto para desplazarse
  • Desplácese dentro de un EditText que está en un ScrollView
  • La posición de desplazamiento salta a los elementos de la lista anterior mientras se desplaza hacia arriba en la vista de lista personalizada
  • Desplazamiento en Horizontal ScrollView pierde el foco del elemento enfocado,
  • Android: Altura total de ScrollView
  • Android listView busca la cantidad de píxeles desplazados
  • Botón de inicio de Android en la barra de herramientas de contracción con imagen
  • Desplazamiento del índice de Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.