Androidはrecyclerviewを用いてGalleryギャラリー効果を実現する(二)
7313 ワード
前言:努力しても成功するとは限らない.努力しなければ成功しない.
一、概説
プロジェクトにはギャラリーの展示効果が必要で、従来はViewpagerでプロパティclipChildrenをfalseに設定して実現していましたが、私の前の記事では詳しく紹介しましたが、ViewPagerで実現したギャラリー効果によって一度に1つしかスライドできず、スライドのスムーズ性はあまりよくありませんが、RecyclerViewを使うと1回に複数スライドでき、中央に表示できます.図:
ソースアドレス:https://github.com/FollowExcellence/RecyclerView_Gallery
二、実現原理
1.RecyclerViewのfling(int velocityX,int velocityY)メソッドを書き換え、RecyclerViewのスライド速度を制御します.
2.support:recyclerview-v 7:24パッケージに非常に重要なクラスSnapHelperを追加し、SnapHelperの実現原理は方法mLinearSnapHelperである.MattachToRecyclerView(mRecyclerView)は、RecyclerViewをリスニングする.OnFlingListenerのonFlingインタフェースは、RecyclerViewをスライドさせて現在のitemを現在のページの真ん中に残す役割を果たしています.
3.スライド中にスケーリングを行う、RecyclerViewのスライドスケーリングは、RecyclerViewのスライド、mRecyclerViewを傍受しなければならない.addOnScrollListener(new RecyclerView.OnScrollListener().
三、実現手順
1.新規クラスはRecyclerViewを継承し、fling(int velocityX,int velocityY)メソッドを書き換え、RecyclerViewのスライド速度を制御します.
2.クラスSnapHelperのRecyclerViewの傍受を実現する.OnFlingListenerのonFlingインタフェース、mLinearSnapHelperバインドRecyclerViewリスニング
上記の方法で中央のビューと中央の位置を見つけ、RecyclerViewを傍受する.OnFlingメソッドで、中央に表示されます.
3.スライド・プロシージャをスケーリングするには、RecyclerViewのaddOnScrollListener(new RecyclerView.OnScrollListener()メソッドをリスニングし、スライド・プロシージャを計算およびスケーリングする必要があります.
mCurrentItemOffsetはスライド総距離であり、ピッチmPagePaddingと左右のカードが見える大きさに基づいてカードの実際の表示幅を計算し、Cardのページごとのスライド距離は固定されており、これに基づいて現在のページ表示の位置を算出することができる.
スライド位置があれば、ページをスライドする割合をリアルタイムで計算し、percentを得て、現在の位置に隣接するビュー呼び出しsetScale関数を取得してスケールを実現します.
4.データと計算サイズを設定し、adapterでRecyclerViewがViewを作成するときonCreateView(ViewGroup parent,int viewType)
Viewの幅の計算
onBindViewHolder(ViewitemView,final int position,int itemCount)でpaddingのサイズを計算する
adapter設定データと方向性
これで、本文は終わります!
ソースアドレス:https://github.com/FollowExcellence/RecyclerView_Gallery
オリジナルの著作権を尊重してください.転載は出典を明記してください.https://blog.csdn.net/m0_37796683/article/details/82497003
一、概説
プロジェクトにはギャラリーの展示効果が必要で、従来はViewpagerでプロパティclipChildrenをfalseに設定して実現していましたが、私の前の記事では詳しく紹介しましたが、ViewPagerで実現したギャラリー効果によって一度に1つしかスライドできず、スライドのスムーズ性はあまりよくありませんが、RecyclerViewを使うと1回に複数スライドでき、中央に表示できます.図:
ソースアドレス:https://github.com/FollowExcellence/RecyclerView_Gallery
二、実現原理
1.RecyclerViewのfling(int velocityX,int velocityY)メソッドを書き換え、RecyclerViewのスライド速度を制御します.
2.support:recyclerview-v 7:24パッケージに非常に重要なクラスSnapHelperを追加し、SnapHelperの実現原理は方法mLinearSnapHelperである.MattachToRecyclerView(mRecyclerView)は、RecyclerViewをリスニングする.OnFlingListenerのonFlingインタフェースは、RecyclerViewをスライドさせて現在のitemを現在のページの真ん中に残す役割を果たしています.
3.スライド中にスケーリングを行う、RecyclerViewのスライドスケーリングは、RecyclerViewのスライド、mRecyclerViewを傍受しなければならない.addOnScrollListener(new RecyclerView.OnScrollListener().
三、実現手順
1.新規クラスはRecyclerViewを継承し、fling(int velocityX,int velocityY)メソッドを書き換え、RecyclerViewのスライド速度を制御します.
public class SpeedRecyclerView extends RecyclerView {
private static final float FLING_SCALE_DOWN_FACTOR = 0.5f; //
private static final int FLING_MAX_VELOCITY = 8000; //
public SpeedRecyclerView(Context context) {
super(context);
}
public SpeedRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public SpeedRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean fling(int velocityX, int velocityY) {
velocityX = solveVelocity(velocityX);
velocityY = solveVelocity(velocityY);
return super.fling(velocityX, velocityY);
}
private int solveVelocity(int velocity) {
if (velocity > 0) {
return Math.min(velocity, FLING_MAX_VELOCITY);
} else {
return Math.max(velocity, -FLING_MAX_VELOCITY);
}
}
}
2.クラスSnapHelperのRecyclerViewの傍受を実現する.OnFlingListenerのonFlingインタフェース、mLinearSnapHelperバインドRecyclerViewリスニング
mLinearSnapHelper.attachToRecyclerView(mRecyclerView);
上記の方法で中央のビューと中央の位置を見つけ、RecyclerViewを傍受する.OnFlingメソッドで、中央に表示されます.
3.スライド・プロシージャをスケーリングするには、RecyclerViewのaddOnScrollListener(new RecyclerView.OnScrollListener()メソッドをリスニングし、スライド・プロシージャを計算およびスケーリングする必要があります.
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
// dx>0 , dx<0 , dy<0 , dy>0
if(dx != 0){//
mCurrentItemOffset += dx;
computeCurrentItemPos();
// LogUtils.v(String.format("dx=%s, dy=%s, mScrolledX=%s", dx, dy, mCurrentItemOffset));
onScrolledChangedCallback();
}
}
});
mCurrentItemOffsetはスライド総距離であり、ピッチmPagePaddingと左右のカードが見える大きさに基づいてカードの実際の表示幅を計算し、Cardのページごとのスライド距離は固定されており、これに基づいて現在のページ表示の位置を算出することができる.
スライド位置があれば、ページをスライドする割合をリアルタイムで計算し、percentを得て、現在の位置に隣接するビュー呼び出しsetScale関数を取得してスケールを実現します.
/**
* RecyclerView , view
*/
private void onScrolledChangedCallback() {
int offset = mCurrentItemOffset - mCurrentItemPos * mOnePageWidth;
float percent = (float) Math.max(Math.abs(offset) * 1.0 / mOnePageWidth, 0.0001);
// LogUtils.d(String.format("offset=%s, percent=%s", offset, percent));
View leftView = null;
View currentView;
View rightView = null;
if (mCurrentItemPos > 0) {
leftView = mRecyclerView.getLayoutManager().findViewByPosition(mCurrentItemPos - 1);
}
currentView = mRecyclerView.getLayoutManager().findViewByPosition(mCurrentItemPos);
if (mCurrentItemPos < mRecyclerView.getAdapter().getItemCount() - 1) {
rightView = mRecyclerView.getLayoutManager().findViewByPosition(mCurrentItemPos + 1);
}
if (leftView != null) {
// y = (1 - mScale)x + mScale
leftView.setScaleY((1 - mScale) * percent + mScale);
}
if (currentView != null) {
// y = (mScale - 1)x + 1
currentView.setScaleY((mScale - 1) * percent + 1);
}
if (rightView != null) {
// y = (1 - mScale)x + mScale
rightView.setScaleY((1 - mScale) * percent + mScale);
}
}
4.データと計算サイズを設定し、adapterでRecyclerViewがViewを作成するときonCreateView(ViewGroup parent,int viewType)
Viewの幅の計算
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
mCardAdapterHelper.onCreateViewHolder(parent, itemView);
return new ViewHolder(itemView);
}
public void onCreateViewHolder(ViewGroup parent, View itemView) {
RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) itemView.getLayoutParams();
lp.width = parent.getWidth() - ScreenUtil.dip2px(itemView.getContext(), 2 * (mPagePadding + mShowLeftCardWidth));
itemView.setLayoutParams(lp);
}
onBindViewHolder(ViewitemView,final int position,int itemCount)でpaddingのサイズを計算する
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
mCardAdapterHelper.onBindViewHolder(holder.itemView, position, getItemCount());
}
public void onBindViewHolder(View itemView, final int position, int itemCount) {
int padding = ScreenUtil.dip2px(itemView.getContext(), mPagePadding);
itemView.setPadding(padding, 0, padding, 0);
int leftMarin = position == 0 ? padding + ScreenUtil.dip2px(itemView.getContext(), mShowLeftCardWidth) : 0;
int rightMarin = position == itemCount - 1 ? padding + ScreenUtil.dip2px(itemView.getContext(), mShowLeftCardWidth) : 0;
setViewMargin(itemView, leftMarin, 0, rightMarin, 0);
}
private void setViewMargin(View view, int left, int top, int right, int bottom) {
ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
if (lp.leftMargin != left || lp.topMargin != top || lp.rightMargin != right || lp.bottomMargin != bottom) {
lp.setMargins(left, top, right, bottom);
view.setLayoutParams(lp);
}
}
adapter設定データと方向性
private void initRecyclerView() {
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
mRecyclerView.setLayoutManager(linearLayoutManager);
mRecyclerView.setAdapter(new MyAdapter(this, mPics));
// mRecyclerView scale
mCardScaleHelper = new CardScaleHelper();
mCardScaleHelper.setCurrentItemPos(1);
mCardScaleHelper.attachToRecyclerView(mRecyclerView);
}
これで、本文は終わります!
ソースアドレス:https://github.com/FollowExcellence/RecyclerView_Gallery
オリジナルの著作権を尊重してください.転載は出典を明記してください.https://blog.csdn.net/m0_37796683/article/details/82497003