Appbarlayout和recyclerview的平滑滚动

时间:2017-06-27 08:28:52

标签: android android-coordinatorlayout

我希望实现像Google Play App一样的平滑滚动行为。我尝试过这里提到的解决方案:

  1. solution 1
  2. solution 2
  3. solution 3
  4. 但上述所有解决方案都没有像Google Play App那样给出预期的结果。 这是xml代码:

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.design.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/layoutContent"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/transparent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
    
    <android.support.design.widget.AppBarLayout
        android:id="@+id/appBarLayout"
        android:layout_width="match_parent"
        android:layout_height="250dp"
        android:background="@android:color/transparent"
        app:elevation="0dp">
    
        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsingToolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">
    
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">
    
                <View
                    android:id="@+id/view1"
                    android:layout_width="match_parent"
                    android:layout_height="125dp"
                    android:background="@android:color/transparent" />
    
                <android.support.v4.view.ViewPager
                    android:id="@+id/pager"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:fitsSystemWindows="true"
                    android:paddingLeft="24dp"
                    android:paddingRight="12dp" />
            </RelativeLayout>
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>
    
    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_margin="@dimen/fab_margin"
        app:backgroundTint="@android:color/white"
        app:layout_anchor="@id/recycler_view"
        app:layout_anchorGravity="bottom|right|end"
        app:srcCompat="@drawable/ic_add_card" />
    </android.support.design.widget.CoordinatorLayout>
    

    如何实现平滑滚动?

    编辑:这是recyclerview适配器

    class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewViewHolder> {
    private static final int DAYS_LEFT_TO_EXPIRE = 3;
    private CardCallback mCallback;
    private List<Ticket> mTickets;
    
    @Inject
    RecyclerViewAdapter() {
        mTickets = new ArrayList<>();
    }
    
    @Override
    public RecyclerViewViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_card, parent, false);
        return new RecyclerViewViewHolder(view);
    }
    
    @Override
    public void onBindViewHolder(final RecyclerViewViewHolder holder, int position) {
        Ticket ticket = mTickets.get(position);
        if (ticket != null) {
            holder.setTicket(ticket);
            if (ticket.getHeadCount() != -1)
                holder.mTxtHeadCount.setText(String.valueOf(ticket.getHeadCount()));
            if (ticket.getType() != null && !ticket.getType().trim().isEmpty())
                setCardTitle(holder.mTxtCardTitle, ticket);
            if (ticket.getBlockCount() != -1)
                holder.mTxtBlockCount.setText(String.valueOf(ticket.getBlockCount()));
            if (ticket.getSeasonalPass() != null && !ticket.getSeasonalPass().trim().isEmpty())
                holder.mCardSeasonalPass.setText(ticket.getSeasonalPass());
            if (ticket.getLastUsedDate() != null)
                holder.mTxtCardLastUsedDate.setText(ticketDateFormatter.format(ticket.getLastUsedDate()));
            if (ticket.getExpiryDate() != null)
                holder.mTxtCardExpiryDate.setText(ticketDateFormatter.format(ticket.getExpiryDate()));
            if (ticket.getSeatingClass() != null && !ticket.getSeatingClass().trim().isEmpty())
                holder.mTxtSeatingClass.setText(ticket.getSeatingClass());
            if (ticket.getTheaterGroup() != null && !ticket.getTheaterGroup().trim().isEmpty())
                holder.mTxtTheaterGroup.setText(ticket.getTheaterGroup());
            if (ticket.getSellerName() != null && !ticket.getSellerName().trim().isEmpty())
                holder.mTxtSellerName.setText(ticket.getSellerName());
            if (ticket.getDescription() != null && !ticket.getDescription().trim().isEmpty())
                holder.mTxtCardDescription.setText(ticket.getDescription());
            if (ticket.getStatus() != null && !ticket.getStatus().trim().isEmpty())
                holder.mTxtCardStatus.setText(ticket.getStatus());
            if (DateUtil.noOfDaysLeft(ticket.getExpiryDate()) <= DAYS_LEFT_TO_EXPIRE)
                holder.mLblWarningMessage.setVisibility(View.VISIBLE);
            else holder.mLblWarningMessage.setVisibility(View.GONE);
            setCardProgress(holder.mCardProgress, ticket);
        }
    }
    
    private void setCardTitle(TextView txtCardTitle, Ticket ticket) {
        switch (ticket.getType()) {
            case Constants.CARD_TYPE_PACK:
                txtCardTitle.setText(ticket.getPackCount() + " " + ticket.getType());
                break;
            case Constants.CARD_TYPE_SEASONAL:
                txtCardTitle.setText(ticket.getType().concat(" pass"));
                break;
            default:
                txtCardTitle.setText(ticket.getType());
                break;
        }
    }
    
    private void setCardProgress(ProgressBar progressBar, Ticket ticket) {
        int maxLimit = 0, progress = 0;
        switch (ticket.getType()) {
            case Constants.CARD_TYPE_SEASONAL:
                maxLimit = (int) TimeUnit.MILLISECONDS.toDays(ticket.getExpiryDate().getTime() - ticket.getLastUsedDate().getTime());
                progress = maxLimit - DateUtil.noOfDaysLeft(ticket.getExpiryDate());
                break;
            case Constants.CARD_TYPE_PACK:
                maxLimit = ticket.getPackCount();
                progress = maxLimit - (ticket.getPackCount() - ticket.getPackUsed());
                break;
            case Constants.CARD_TYPE_TICKET:
                maxLimit = (int) TimeUnit.MILLISECONDS.toDays(ticket.getExpiryDate().getTime() - ticket.getTicketBoughtDate().getTime());
                progress = maxLimit - DateUtil.noOfDaysLeft(ticket.getExpiryDate());
                break;
        }
        progressBar.setMax(maxLimit);
        if (progress < 0) {
            progressBar.setProgress(maxLimit);
        } else {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
                progressBar.setProgress(progress, true);
            else progressBar.setProgress(progress);
        }
    }
    
    @Override
    public int getItemCount() {
        return mTickets.size();
    }
    
    void setTickets(List<Ticket> tickets) {
        if (tickets != null && !tickets.isEmpty()) {
            mTickets.addAll(tickets);
            notifyDataSetChanged();
        }
    }
    
    void setCallback(CardCallback callback) {
        this.mCallback = callback;
    }
    
    void clearTicketList() {
        mTickets.clear();
        notifyItemRangeChanged(0, mTickets.size());
    }
    
    interface CardCallback {
        void onBtnMoreCardInfoClicked(Ticket ticket, LinearLayout layout, ImageButton imageButton);
    }
    
    class RecyclerViewViewHolder extends RecyclerView.ViewHolder {
        @BindView(R.id.txt_head_count)
        TextView mTxtHeadCount;
        @BindView(R.id.txt_card_type)
        TextView mTxtCardTitle;
        @BindView(R.id.txt_block_count)
        TextView mTxtBlockCount;
        @BindView(R.id.txt_seasonal_pass)
        TextView mCardSeasonalPass;
        @BindView(R.id.txt_card_last_used_date)
        TextView mTxtCardLastUsedDate;
        @BindView(R.id.txt_card_expiry_date)
        TextView mTxtCardExpiryDate;
        @BindView(R.id.card_progress)
        ProgressBar mCardProgress;
        @BindView(R.id.txt_seating_class)
        TextView mTxtSeatingClass;
        @BindView(R.id.txt_theater_group)
        TextView mTxtTheaterGroup;
        @BindView(R.id.txt_seller_name)
        TextView mTxtSellerName;
        @BindView(R.id.btn_more_card_info)
        ImageButton mBtnMoreCardInfo;
        @BindView(R.id.layout_card_description)
        LinearLayout mLayoutCardDescription;
        @BindView(R.id.txt_card_description)
        TextView mTxtCardDescription;
        @BindView(R.id.txt_card_status)
        TextView mTxtCardStatus;
        @BindView(R.id.lbl_warning_message)
        TextView mLblWarningMessage;
    
        private Ticket mTicket;
    
        NFCCardRecyclerViewViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
    
            mBtnMoreCardInfo.setOnClickListener(v -> {
                if (mCallback != null)
                    mCallback.onBtnMoreCardInfoClicked(mTicket, mLayoutCardDescription, mBtnMoreCardInfo);
            });
        }
    
        void setTicket(Ticket mTicket) {
            this.mTicket = mTicket;
        }
    }
    

    }

1 个答案:

答案 0 :(得分:0)

按照此链接中的步骤操作:smooth app bar layout 这个图书馆帮助我解决了我的问题。