Erhalten Sie beim Scrollen ein sichtbares Element von RecycleView in der Mitte
Lesezeit: 19 Minuten
Ductran
Das ist was ich will:
Als Bild oben möchte ich eine Mittellinie zeichnen RecycleViewdann erhalten Sie das mittlere Element beim Scrollen (sowie nach links oder rechts bewegen)
Hier ist mein Versuch, eine Horizontale zu zeichnen RecycleView:
HorizontalAdapter adapter = new HorizontalAdapter(data);
LinearLayoutManager layoutManager
= new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
recycleView.setLayoutManager(layoutManager);
recycleView.setAdapter(adapter);
Gibt es eine Möglichkeit zu wissen, welches Element in die Mitte verschoben wird? RecycleView? Und wie kann ich scrollen RecycleView nach links oder rechts nur eine Position?
Aktualisieren: Ich habe versucht, einen Scroll-Listener zu verwenden, um die mittlere Position zu erhalten, aber es funktioniert nicht als Aspekt.
@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();
}
Und erhalten Sie das Ergebnis:
Ich möchte das ausgewählte Element nur ändern (Text in weiße Farbe umwandeln), wenn es blau ist Rect
und was list_item_padding Layout enthält, können Sie mir sagen? können Sie mir sagen
– Mahesh Suthar
21. Dezember 16 um 5:47 Uhr
@MaheshSuthar es ist nur ein leeres Layout mit gleicher Elementbreite
– Ductran
21. Dezember 16 um 8:10 Uhr
tut mir leid, aber es funktioniert nicht
– Mahesh Suthar
21. Dezember 16 um 11:31 Uhr
Können Sie mir sagen, wie es funktioniert, wenn der Benutzer auf das Datum klickt und das Datum in der Mitte steht?
– Mahesh Suthar
21. Dezember 16 um 12:11 Uhr
@MaheshSuthar Was hast du versucht? Wenn es nicht funktionieren kann, sollten Sie eine andere Frage erstellen. Versuchen Sie, die Antwort von TranHieu sorgfältig zu lesen, der Algorithmus ist darauf ausgelegt. Ich habe die Antwort von TranHieu verwendet und an meine Bedürfnisse angepasst.
– Ductran
22. Dezember 16 um 3:10 Uhr
Ich habe so etwas gemacht. Ich kann genau das tun, was Sie brauchen. Zunächst einmal, so funktioniert meine Rechenarbeit
Das ist mein recyclerView Adapter
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);
}
}}
Dies ist der wichtigste Algorithmus:
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);
}
Und das ist mein Ergebnis:
Schau dieses Video an Verknüpfungdas ist meine App-Demo
Irgendetwas stimmt mit Ihrem Code nicht. Der paddingDate wird nie geändert. Also die Formel (allPixelsDate + paddingDate - firstItemWidthDate) / itemWidthDate ist gleich allPixelsDate/itemWidthDateund geben Sie die falsch ausgewählte Position zurück
– Ductran
7. Januar 16 um 15:00 Uhr
Nun, ich denke, die Position des ersten Artikels in recyclerView (keine Auffüllung) ist 0, und sein Artikel ist Nummer 1. Das heißt, wenn Sie die richtige Nummer erhalten möchten, müssen Sie +1 geben. Ich habe es bei setDateValue() gemacht. Tks für deine Antwort
– TranHieu
8. Januar 16 um 3:17 Uhr
Meine Artikelbreite ist 100dp und meine mittlere Artikelbreite ist 200dp. Wie kann ich dies mit unterschiedlichen Artikelbreiten implementieren?
– Ibrahim Disouki
21. Mai 16 um 17:29 Uhr
@hema18 in meinem onBindViewHolder Ich habe eine Variable namens selectedItem. Schau es dir einfach an. Es entscheidet, welches Element in der Mitte ist.
– TranHieu
22. Mai 16 um 16:57 Uhr
Der Screenshot stammt von einem iOS-Gerät? Das ist etwas verwirrend.
– Asme Just
15. November 17 um 4:57 Uhr
stillsudo
Manchmal wird der gesamte Beispielcodeblock zusammen benötigt, da wir möglicherweise etwas übersehen. Hier ist, was ich habe, fühlen Sie sich frei, etwas zu korrigieren, da ich vielleicht irgendwo einen kleinen Fehler mache. Und ja, diese Antwort ist eine Erweiterung der @tranhieu-Antwort. Danke @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;
}
}
}
Und dann einfach zuweisen SnapHelper zu deinem RecylcerView:
val snapHelper = LinearSnapHelper()
snapHelper.attachToRecyclerView(recyclerView)
Das ist es. Die einfachste und perfekteste Lösung für das Problem
Diese Lösung funktioniert nur, wenn die RecyclerViewer Breite und die Breite des ersten und letzten Elements ist so, dass 150dp = RV.width * 0.5f - item.width * 0.5f Ändert sich die Artikelbreite gegenüber der RecyclerView Die ersten und letzten Elemente werden immer falsch ausgerichtet, da dies auf der Verwendung statischer Breiten für das RV und seine Elemente beruht und erwartet, dass sie immer fest bleiben. Es ist keine sehr gute Lösung wegen des völligen Mangels an Flexibilität.
Wie von TranHieu gesagt, ist die Lösung zum Einfügen von 2 Artikeln zum Auffüllen (an der Start- und an der Endposition) gut.
Ich mag die Verwendung von ViewTreeObserver wegen der schlechten Lesbarkeit des Codes nicht. Bei dieser Technik müssen Sie auch das Neuzeichnen der Elemente verwalten, wenn sie recycelt werden.
Wenn Sie benutzerdefinierte Ansichtsklassen verwenden, können Sie die Breite direkt in diesen Klassen festlegen.
Das ist zum Beispiel meine Padding-Klasse
/**
* 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));
}
}
In meinem Adapter speichere ich die gewünschte Padding-Item-Breite, also gleich (displayWidth / 2) – (realItemWidth / 2)
Dies ist mein Adapter, schauen Sie sich keine Methoden an, die nicht mit RecyclerView.Adapter übereinstimmen, achten Sie auf die Methode initAdapter und die Methode 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;
}
}
Ich verwende die AndroidAnnotations-Bibliothek, aber sie ist nicht erforderlich
hoffentlich hilft das
Dionis Beqiraj
VERWENDUNG VON SNAPHELPER – EINE REIBUNGSLOSE LÖSUNG
Hier ist es eine andere Lösung mit SnapHelper. Ausgehend von der Antwort von @TranHieu hier:
https://stackoverflow.com/a/34647005/3944251
und das komprimierte von @sector11 hier:
https://stackoverflow.com/a/38411582/3944251
Ich habe den folgenden Code geschrieben, der auch auf den beiden obigen Antworten basiert, aber einfacher ist und eine reibungslosere Lösung mit SnapHelper bietet, die in vorgestellt wird Android-Unterstützungsbibliothek 24.2.0.
Hier haben Sie die Hauptaktivität Klasse. Der Rest ist der gleiche wie bei der Antwort von @ Sector11.
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.LinearSnapHelper;
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 AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
public float firstItemWidthDate;
public float itemWidthDate;
public int allPixelsDate;
public int finalWidthDate;
private DateAdapter dateAdapter;
private ArrayList<LabelerDate> labelerDates;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
labelerDates = new ArrayList<>();
getRecyclerviewDate();
}
public void getRecyclerviewDate() {
final RecyclerView recyclerViewDate = (RecyclerView) findViewById(R.id.rv_tasks_date);
recyclerViewDate.postDelayed(new Runnable() {
@Override
public void run() {
//recyclerViewDate.smoothScrollToPosition(dateAdapter.getItemCount()-1);
setDateValue();
}
}, 300);
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);
firstItemWidthDate = (finalWidthDate - itemWidthDate) / 2;
allPixelsDate = 0;
final LinearLayoutManager dateLayoutManager = new LinearLayoutManager(getApplicationContext());
dateLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerViewDate.setLayoutManager(dateLayoutManager);
/* Create a LinearSnapHelper and attach the recyclerView to it. */
final LinearSnapHelper snapHelper = new LinearSnapHelper();
snapHelper.attachToRecyclerView(recyclerViewDate);
recyclerViewDate.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
allPixelsDate += dx;
recyclerView.post(new Runnable() {
public void run() {
setDateValue();
}
});
}
});
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);
}
}
}
//
private void setDateValue() {
int expectedPositionDateColor = Math.round(allPixelsDate / 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 DateAdapter.DateViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
if (viewType == VIEW_TYPE_PADDING) {
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) view.getLayoutParams();
layoutParams.width = paddingWidthDate;
view.setLayoutParams(layoutParams);
}
return new DateViewHolder(view);
}
@Override
public void onBindViewHolder(DateAdapter.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;
}
}
}
Aber das erste Element beginnt in der Mitte. Also der letzte Artikel. Wie lässt sich das erste Element von links und das letzte Element von rechts starten?
– Ankit Kamboj
8. Februar 18 um 13:28 Uhr
@Dionis, was ist “item_db_width”?
– Manikandan
20. August 18 um 7:49 Uhr
Ich weiß nicht, was ich für “item_db_width” geben soll. Ich gebe nur 20 dafür. Und das mittlere Element wird beim ersten Laden ausgewählt. Beim manuellen Scrollen wird das mittlere Element nicht ausgewählt.
– Manikandan
20. August 18 um 08:57 Uhr
@Manikandan item_dob_width ist der in definierte Wert item.xml in der Antwort von @ Sector11 hier: stackoverflow.com/a/38411582/3944251. Kopiere alles .xml Dateien aus seiner Antwort und Kopie MyActivity Code aus meiner Antwort, um eine Vorstellung davon zu bekommen, wie es funktioniert.
– Dionis Beqiraj
21. August 18 um 08:21 Uhr
Paresh Mangukiya
Wie in der anderen Antwort erwähnt, gibt es keine direkte Möglichkeit, dies zu tun.
Auf diese Weise können Sie wahrscheinlich das erreichen, was Sie in der Frage beschrieben haben.
Kennen Sie die Anzahl der auf dem Bildschirm sichtbaren Elemente.
Wählen Sie das mittlere Element programmgesteuert jedes Mal aus, wenn die Ansicht gescrollt wird.
Behalten Sie ein teilweise transparentes Bild als Overlay auf dem mittleren Element in der Recycleransicht bei. (Sie müssen die Koordinaten basierend auf der Breite der Recycler-Ansicht oder der Breite des Bildschirms und der Breite des Überlagerungsbilds berechnen, das Sie einfügen möchten.
Aktualisiert den ausgewählten Wert in einer Textansicht unterhalb der Recycler-Ansicht bei jedem Bildlauf.
Die Bildüberlagerungen müssen so platziert werden, dass sie zusammenhängend und als ein einziges Steuerelement erscheinen.
Aber das erste Element beginnt in der Mitte. Also der letzte Artikel. Wie lässt sich das erste Element von links und das letzte Element von rechts starten?
– Ankit Kamboj
8. Februar 18 um 13:28 Uhr
@Dionis, was ist “item_db_width”?
– Manikandan
20. August 18 um 7:49 Uhr
Ich weiß nicht, was ich für “item_db_width” geben soll. Ich gebe nur 20 dafür. Und das mittlere Element wird beim ersten Laden ausgewählt. Beim manuellen Scrollen wird das mittlere Element nicht ausgewählt.
– Manikandan
20. August 18 um 08:57 Uhr
@Manikandan item_dob_width ist der in definierte Wert item.xml in der Antwort von @ Sector11 hier: stackoverflow.com/a/38411582/3944251. Kopiere alles .xml Dateien aus seiner Antwort und Kopie MyActivity Code aus meiner Antwort, um eine Vorstellung davon zu bekommen, wie es funktioniert.
– Dionis Beqiraj
21. August 18 um 08:21 Uhr
veeyikpong
Sie können eine verwenden LinearSnapHelper
An Ihren Recycler anhängenGefällt mir anzeigen
val snapHelper = LinearSnapHelper()
snapHelper.attachToRecyclerView(this)
Verwenden Sie dann, um die Mittelansicht zu erhalten snapHelper.findSnapView(horizontalScrollView.layoutManager)?
.
7575400cookie-checkErhalten Sie beim Scrollen ein sichtbares Element von RecycleView in der Mitteyes
und was list_item_padding Layout enthält, können Sie mir sagen? können Sie mir sagen
– Mahesh Suthar
21. Dezember 16 um 5:47 Uhr
@MaheshSuthar es ist nur ein leeres Layout mit gleicher Elementbreite
– Ductran
21. Dezember 16 um 8:10 Uhr
tut mir leid, aber es funktioniert nicht
– Mahesh Suthar
21. Dezember 16 um 11:31 Uhr
Können Sie mir sagen, wie es funktioniert, wenn der Benutzer auf das Datum klickt und das Datum in der Mitte steht?
– Mahesh Suthar
21. Dezember 16 um 12:11 Uhr
@MaheshSuthar Was hast du versucht? Wenn es nicht funktionieren kann, sollten Sie eine andere Frage erstellen. Versuchen Sie, die Antwort von TranHieu sorgfältig zu lesen, der Algorithmus ist darauf ausgelegt. Ich habe die Antwort von TranHieu verwendet und an meine Bedürfnisse angepasst.
– Ductran
22. Dezember 16 um 3:10 Uhr