Ich habe ein Projekt, wo ich eine horizontale Recycler-Ansicht verwende und ich möchte ein Element zentrieren. Meine Implementierung funktioniert, aber nicht in jedem Fall diese GIF hier überprüfen:RecyclerView scrollt nicht wie erwartet
Wie Sie feststellen, kann es scrollt richtig, wenn ich von links kommen. Wenn ich von rechts komme, überspringt es sehr viel und ich habe keine Ahnung, wie ich aufhören oder reparieren kann.
gestreift ich meinen Code auf dieses Beispiel hier:
public class DemoActivity extends ActionBarActivity implements View.OnClickListener {
private static final int JUMP_TO_LEFT = MyAdapter.NON_VISIBLE_ITEMS + MyAdapter.VISIBLE_ITEMS - 1;
private static final int JUMP_TO_RIGHT = MyAdapter.NON_VISIBLE_ITEMS;
private LinearLayoutManager mLayoutManager;
private RecyclerView mRecycler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo);
findViewById(android.R.id.button1).setOnClickListener(this);
mRecycler = (RecyclerView)findViewById(R.id.recycler);
MyAdapter mAdapter = new MyAdapter();
mLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
mRecycler.setLayoutManager(mLayoutManager);
mRecycler.setHasFixedSize(true);
mRecycler.scrollToPosition(MyAdapter.NON_VISIBLE_ITEMS);
mRecycler.setAdapter(mAdapter);
}
@Override
public void onClick(View v) {
int pos = mLayoutManager.findFirstVisibleItemPosition();
int outer = (MyAdapter.VISIBLE_ITEMS - 1)/2;
if(pos + outer >= MyAdapter.ITEM_IN_CENTER) {
mRecycler.smoothScrollToPosition(JUMP_TO_RIGHT);
} else {
mRecycler.smoothScrollToPosition(JUMP_TO_LEFT);
}
}
}
Und hier ist mein Adapter:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.Holder> implements View.OnClickListener {
public static final int VISIBLE_ITEMS = 7;
public static final int NON_VISIBLE_ITEMS = 150;
private static final int TOTAL_ITEMS = VISIBLE_ITEMS + NON_VISIBLE_ITEMS * 2;
public static final int ITEM_IN_CENTER = (int)Math.ceil(VISIBLE_ITEMS/2f) + NON_VISIBLE_ITEMS;
private Calendar mCalendar;
public MyAdapter() {
mCalendar = GregorianCalendar.getInstance();
setHasStableIds(true);
}
private int getToday() {
return (int)TimeUnit.MILLISECONDS.toDays(System.currentTimeMillis());
}
@Override
public int getItemCount() {
return TOTAL_ITEMS;
}
@Override
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
final TextView tv = new TextView(parent.getContext());
int width = parent.getWidth()/VISIBLE_ITEMS;
tv.setLayoutParams(new TableRow.LayoutParams(width, ViewGroup.LayoutParams.MATCH_PARENT, 1));
tv.setGravity(Gravity.CENTER);
tv.setBackgroundColor(Color.TRANSPARENT);
DisplayMetrics metrics = tv.getContext().getResources().getDisplayMetrics();
float padding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, metrics);
tv.setLineSpacing(padding, 1f);
tv.setPadding(0, (int)padding, 0, 0);
tv.setOnClickListener(this);
return new Holder(tv);
}
@Override
public void onBindViewHolder(Holder holder, int position) {
int today = getToday();
mCalendar.setTimeInMillis(System.currentTimeMillis());
mCalendar.set(Calendar.HOUR_OF_DAY, 12); // set to noon to avoid energy saver time problems
mCalendar.add(Calendar.DAY_OF_YEAR, position - ITEM_IN_CENTER + 1);
DateFormat format = new SimpleDateFormat("E\nd");
String label = format.format(mCalendar.getTime()).replace(".\n", "\n");
int day = (int)TimeUnit.MILLISECONDS.toDays(mCalendar.getTimeInMillis());
holder.update(day, today, label);
}
@Override
public long getItemId(int position) {
mCalendar.setTimeInMillis(System.currentTimeMillis());
mCalendar.set(Calendar.HOUR_OF_DAY, 12); // set to noon to avoid energy saver time problems
mCalendar.add(Calendar.DAY_OF_YEAR, position - ITEM_IN_CENTER + 1);
DateFormat format = new SimpleDateFormat("dMMyyyy");
return Long.parseLong(format.format(mCalendar.getTime()));
}
@Override
public void onClick(View v) {
String day = ((TextView)v).getText().toString().replace("\n", " ");
Toast.makeText(v.getContext(), "You clicked on " + day, Toast.LENGTH_SHORT).show();
}
public class Holder extends RecyclerView.ViewHolder {
private final Typeface font;
private Holder(TextView v) {
super(v);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
font = Typeface.create("sans-serif-light", Typeface.NORMAL);
} else {
font = null;
}
}
public void update(int day, int today, String label) {
TextView tv = (TextView)itemView;
tv.setText(label);
if(day == today) {
tv.setTextSize(18);
tv.setTypeface(null, Typeface.BOLD);
} else {
tv.setTextSize(16);
tv.setTypeface(font, Typeface.NORMAL);
}
tv.setBackgroundColor(0xff8dc380);
}
}
}
Sehen Sie einen Grund dafür? Um es für Sie einfacher zu machen, habe ich diesen Code auch auf GitHub gesetzt. https://github.com/rekire/RecylcerViewBug
Sie können für die horizontalen Wähler FancyCoverFlow versuchen. Es funktioniert wie viewpager – berserk
@berserk, dass lib die veraltete 'GalleryView' verwendet, die ich nicht verwenden möchte. – rekire
Bitte legen Sie diese SimpleDateFormat als Felder, Erstellen von zwei pro Ansicht Recycling ist zu viel. –