RecyclerView scrollt nicht wie erwartet

Ich habe ein Projekt, in dem ich eine horizontale Recycler-Ansicht verwende und ein Element zentrieren möchte. Meine Implementierung funktioniert, aber überprüfen Sie dieses GIF hier nicht in jedem Fall:

ie Sie vielleicht bemerken, scrollt es richtig, wenn ich von links komme. Wenn ich von rechts komme, überrollt es viel und ich habe keine Ahnung, wie ich damit aufhören soll oder wie ich das beheben soll.

Ich habe meinen Code für dieses Beispiel hier gestreift:

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 Ihnen einfacher zu machen, habe ich diesen Code auch auf GitHub gestellt.https: //github.com/rekire/RecylcerViewBu

Antworten auf die Frage(4)

Ihre Antwort auf die Frage