Android基于reclyview實(shí)現(xiàn)列表回彈動(dòng)畫效果
reclyview實(shí)現(xiàn)列表回彈動(dòng)畫效果,供大家參考,具體內(nèi)容如下
1.reclyview列表布局文件
<com.example.demo1.ReboundLayout ? ? ? ? android:id="@+id/view" ? ? ? ? android:layout_width="match_parent" ? ? ? ? android:layout_height="match_parent" ? ? ? ? android:background="#000"> ? ? ? ? ? ? <androidx.recyclerview.widget.RecyclerView ? ? ? ? ? ? ? ? android:id="@+id/rv" ? ? ? ? ? ? ? ? android:layout_width="match_parent" ? ? ? ? ? ? ? ? android:layout_height="match_parent" ? ? ? ? ? ? ? ? android:fadingEdgeLength="30px" ? ? ? ? ? ? ? ? android:requiresFadingEdge="horizontal"/> </com.example.demo1.ReboundLayout>
2.item布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" ? ? android:layout_width="wrap_content" ? ? android:layout_height="wrap_content" ? ? android:layout_marginTop="40px" ? ? android:layout_gravity="center_vertical"> ? ? <ImageView ? ? ? ? android:id="@+id/card_item_img" ? ? ? ? android:layout_width="wrap_content" ? ? ? ? android:layout_height="wrap_content" ? ? ? ? android:layout_marginLeft="20dp" ? ? ? ? android:layout_marginRight="20dp"/> </LinearLayout>
3.適配adapter
public class HomeCardAdapter extends RecyclerView.Adapter<HomeCardAdapter.ViewHolder> { ? ? private LayoutInflater mInflater; ? ? private List<Integer> mDatas; ? ? private OnItemClickListener mOnItemClickListener; ? ? private Context mContext; ? ? public HomeCardAdapter(Context context, List<Integer> datats) { ? ? ? ? mInflater = LayoutInflater.from(context); ? ? ? ? mDatas = datats; ? ? ? ? mContext = context; ? ? } ? ? public class ViewHolder extends RecyclerView.ViewHolder { ? ? ? ? public ViewHolder(View arg0) { ? ? ? ? ? ? super(arg0); ? ? ? ? } ? ? ? ? ImageView mImg; ? ? } ? ? public interface OnItemClickListener{ ? ? ? ? void ?onClick(int position); ? ? } ? ? public ?void ?setOnItemClickListener(OnItemClickListener onItemClickListener ){ ? ? ? ? this.mOnItemClickListener =onItemClickListener; ? ? } ? ? @Override ? ? public int getItemCount() { ? ? ? ? return mDatas.size(); ? ? } ? ? /** ? ? ?* 創(chuàng)建ViewHolder ? ? ?*/ ? ? @Override ? ? public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { ? ? ? ? View view = mInflater.inflate(R.layout.card_item, ? ? ? ? ? ? ? ? viewGroup, false); ? ? ? ? ViewHolder viewHolder = new ViewHolder(view); ? ? ? ? viewHolder.mImg = (ImageView) view.findViewById(R.id.card_item_img); ? ? ? ? return viewHolder; ? ? } ? ? /** ? ? ?* 設(shè)置值 ? ? ?*/ ? ? @Override ? ? public void onBindViewHolder(final ViewHolder viewHolder, @SuppressLint("RecyclerView")int i) { ? ? ? ? viewHolder.mImg.setImageResource(mDatas.get(i)); ? ? ? ? if( mOnItemClickListener!= null){ ? ? ? ? ? ? viewHolder.itemView.setOnClickListener( new View.OnClickListener() { ? ? ? ? ? ? ? ? @Override ? ? ? ? ? ? ? ? public void onClick(View v) { ? ? ? ? ? ? ? ? ? ? mOnItemClickListener.onClick(i); ? ? ? ? ? ? ? ? ? ? //卡片點(diǎn)擊動(dòng)畫 ? ? ? ? ? ? ? ? ? ? Animation animation = AnimationUtils.loadAnimation(mContext, R.anim.scale_card); ? ? ? ? ? ? ? ? ? ? viewHolder.itemView.startAnimation(animation); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? }); ? ? ? ? } ? ? } }
4.自定義彈性view
public class ReboundLayout extends LinearLayout implements NestedScrollingParent { ? ? private View mHeaderView; ? ? private View mFooterView; ? ? private static final int MAX_WIDTH = 200; ? ? private View mChildView; ? ? // 解決多點(diǎn)觸控問題 ? ? private boolean isRunAnim; ? ? private boolean isFlag = false; ? ? private int mDrag = 6;//除數(shù)越大可以滑動(dòng)的距離越短 ? ? public ReboundLayout(Context context, AttributeSet attrs) { ? ? ? ? super(context, attrs); ? ? ? ? setOrientation(LinearLayout.HORIZONTAL); ? ? ? ? mHeaderView = new View(context); ? ? ? ? mHeaderView.setBackgroundColor(0xfff); ? ? ? ? mFooterView = new View(context); ? ? ? ? mFooterView.setBackgroundColor(0xfff); ? ? } ? ? public boolean isFlag() { ? ? ? ? return isFlag; ? ? } ? ? public void setFlag(boolean flag) { ? ? ? ? isFlag = flag; ? ? } ? ? @Override ? ? protected void onFinishInflate() { ? ? ? ? super.onFinishInflate(); ? ? ? ? mChildView = getChildAt(0); ? ? ? ? LayoutParams layoutParams = new LayoutParams(MAX_WIDTH, LayoutParams.MATCH_PARENT); ? ? ? ? addView(mHeaderView, 0, layoutParams); ? ? ? ? addView(mFooterView, getChildCount(), layoutParams); ? ? ? ? // 左移 ? ? ? ? scrollBy(MAX_WIDTH, 0); ? ? } ? ? @Override ? ? protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { ? ? ? ? super.onMeasure(widthMeasureSpec, heightMeasureSpec); ? ? ? ? ViewGroup.LayoutParams params = mChildView.getLayoutParams(); ? ? ? ? params.width = getMeasuredWidth(); ? ? } ? ? /** ? ? ?* 必須要復(fù)寫 onStartNestedScroll后調(diào)用 ? ? ?*/ ? ? @Override ? ? public void onNestedScrollAccepted(View child, View target, int axes) { ? ? } ? ? /** ? ? ?* 返回true代表處理本次事件 ? ? ?*/ ? ? @Override ? ? public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) { ? ? ? ? if (target instanceof RecyclerView && !isRunAnim) { ? ? ? ? ? ? return true; ? ? ? ? } ? ? ? ? return false; ? ? } ? ? /** ? ? ?* 復(fù)位初始位置 ? ? ?*/ ? ? @Override ? ? public void onStopNestedScroll(View target) { ? ? ? ?startAnimation(new ProgressAnimation()); ? ? } ? ? /** ? ? ?* 回彈動(dòng)畫 ? ? ?*/ ? ? private class ProgressAnimation extends Animation { ? ? ? ? // 預(yù)留 ? ? ? ? private float startProgress = 0; ? ? ? ? private float endProgress = 1; ? ? ? ? private ProgressAnimation() { ? ? ? ? ? ? isRunAnim = true; ? ? ? ? } ? ? ? ? @Override ? ? ? ? protected void applyTransformation(float interpolatedTime, Transformation t) { ? ? ? ? ? ? float progress = ((endProgress - startProgress) * interpolatedTime) + startProgress; ? ? ? ? ? ? scrollBy((int) ((MAX_WIDTH - getScrollX()) * progress), 0); ? ? ? ? ? ? if (progress == 1) { ? ? ? ? ? ? ? ? //滑動(dòng)停止 ? ? ? ? ? ? ? ? isRunAnim = false; ? ? ? ? ? ? ? ? isFlag = false; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? @Override ? ? ? ? public void initialize(int width, int height, int parentWidth, int parentHeight) { ? ? ? ? ? ? super.initialize(width, height, parentWidth, parentHeight); ? ? ? ? ? ? setDuration(200); ? ? ? ? } ? ? } ? ? @Override ? ? public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int ? ? ? ? ? ? dyUnconsumed) { ? ? } ? ? @Override ? ? public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) { ? ? ? ? // 如果在自定義ViewGroup之上還有父View交給我來處理 ? ? ? ? getParent().requestDisallowInterceptTouchEvent(true); ? ? ? ? // dx>0 往左滑動(dòng) dx<0往右滑動(dòng) ? ? ? ? boolean hiddenLeft = dx > 0 && getScrollX() < MAX_WIDTH && !ViewCompat ? ? ? ? ? ? ? ? .canScrollHorizontally(target, -1); ? ? ? ? boolean showLeft = dx < 0 && !ViewCompat.canScrollHorizontally(target, -1); ? ? ? ? boolean hiddenRight = dx < 0 && getScrollX() > MAX_WIDTH && !ViewCompat ? ? ? ? ? ? ? ? .canScrollHorizontally(target, 1); ? ? ? ? boolean showRight = dx > 0 && !ViewCompat.canScrollHorizontally(target, 1); ? ? ? ? if (hiddenLeft || showLeft || hiddenRight || showRight) { ? ? ? ? ? ? scrollBy(dx / mDrag, 0); ? ? ? ? ? ? consumed[0] = dx; ? ? ? ? } ? ? ? ? // 限制錯(cuò)位問題 ? ? ? ? if (dx > 0 && getScrollX() > MAX_WIDTH && !ViewCompat.canScrollHorizontally(target, -1)) { ? ? ? ? ? ? scrollTo(MAX_WIDTH, 0); ? ? ? ? } ? ? ? ? if (dx < 0 && getScrollX() < MAX_WIDTH && !ViewCompat.canScrollHorizontally(target, 1)) { ? ? ? ? ? ? scrollTo(MAX_WIDTH, 0); ? ? ? ? } ? ? ? ? isFlag = true; ? ? } ? ? @Override ? ? public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) { ? ? ? ? return false; ? ? } ? ? @Override ? ? public boolean onNestedPreFling(View target, float velocityX, float velocityY) { ? ? ? ? // 當(dāng)RecyclerView在界面之內(nèi)交給它自己慣性滑動(dòng) ? ? ? ? if (getScrollX() == MAX_WIDTH) { ? ? ? ? ? ? return false; ? ? ? ? } ? ? ? ? return true; ? ? } ? ? @Override ? ? public int getNestedScrollAxes() { ? ? ? ? return 0; ? ? } ? ? /** ? ? ?* 限制滑動(dòng) 移動(dòng)x軸不能超出最大范圍 ? ? ?*/ ? ? @Override ? ? public void scrollTo(int x, int y) { ? ? ? ? if (x < 0) { ? ? ? ? ? ? x = 0; ? ? ? ? } else if (x > MAX_WIDTH * 2) { ? ? ? ? ? ? x = MAX_WIDTH * 2; ? ? ? ? } ? ? ? ? super.scrollTo(x, y); ? ? } }
5.activity調(diào)用
public class MainActivity extends AppCompatActivity { ? ? private List<Integer> mDatas; ? ? private RecyclerView mRecyclerView; ? ? private HomeCardAdapter mAdapter; ? ? private ReboundLayout movingView; ? ? private LinearLayout linearLayout; ? ? @Override ? ? protected void onCreate(Bundle savedInstanceState) { ? ? ? ? super.onCreate(savedInstanceState); ? ? ? ? setContentView(R.layout.activity_main); ? ? ? ? initData(); ? ? ? ? LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); ? ? ? ? linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); ? ? ? ? mRecyclerView.setLayoutManager(linearLayoutManager); ? ? ? ? //設(shè)置適配器 ? ? ? ? mAdapter = new HomeCardAdapter(this, mDatas); ? ? ? ? mRecyclerView.setAdapter(mAdapter); ? ? ? ? mAdapter.setOnItemClickListener(new HomeCardAdapter.OnItemClickListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onClick(int position) { ? ? ? ? ? ? ? ? switch (position){ ? ? ? ? ? ? ? ? ? ? case 0: ? ? ? ? ? ? ? ? ? ? ? ? Toast.makeText(MainActivity.this, "第"+position+"個(gè)", Toast.LENGTH_SHORT).show(); ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? case 1: ? ? ? ? ? ? ? ? ? ? ? ? Toast.makeText(MainActivity.this, "第"+position+"個(gè)", Toast.LENGTH_SHORT).show(); ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? case 2: ? ? ? ? ? ? ? ? ? ? ? ? Toast.makeText(MainActivity.this, "第"+position+"個(gè)", Toast.LENGTH_SHORT).show(); ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? case 3: ? ? ? ? ? ? ? ? ? ? ? ? Toast.makeText(MainActivity.this, "第"+position+"個(gè)", Toast.LENGTH_SHORT).show(); ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? case 4: ? ? ? ? ? ? ? ? ? ? ? ? Toast.makeText(MainActivity.this, "第"+position+"個(gè)", Toast.LENGTH_SHORT).show(); ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? case 5: ? ? ? ? ? ? ? ? ? ? ? ? Toast.makeText(MainActivity.this, "第"+position+"個(gè)", Toast.LENGTH_SHORT).show(); ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? case 6: ? ? ? ? ? ? ? ? ? ? ? ? Toast.makeText(MainActivity.this, "第"+position+"個(gè)", Toast.LENGTH_SHORT).show(); ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? case 7: ? ? ? ? ? ? ? ? ? ? ? ? Toast.makeText(MainActivity.this, "第"+position+"個(gè)", Toast.LENGTH_SHORT).show(); ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onScrollStateChanged(@NonNull @NotNull RecyclerView recyclerView, int newState) { ? ? ? ? ? ? ? ? super.onScrollStateChanged(recyclerView, newState); ? ? ? ? ? ? ? ? if (newState == RecyclerView.SCROLL_STATE_IDLE && movingView.isFlag()) { ? ? ? ? ? ? ? ? ? ? if (!recyclerView.canScrollHorizontally(1)) { ? ? ? ? ? ? ? ? ? ? ? ? //回彈動(dòng)畫 ? ? ? ? ? ? ? ? ? ? ? ? springAnim(movingView,-100,0,200,6); ? ? ? ? ? ? ? ? ? ? } else if (!recyclerView.canScrollHorizontally(-1)) { ? ? ? ? ? ? ? ? ? ? ? ? springAnim(mRecyclerView,100,0,200,6); ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? movingView.setFlag(false); ? ? ? ? ? ? } ? ? ? ? }); ? ? } ? ? private void initData() { ? ? ? ? movingView = findViewById(R.id.view); ? ? ? ? linearLayout = findViewById(R.id.home_card_layout); ? ? ? ? mRecyclerView = findViewById(R.id.rv); ? ? ? ? mDatas = new ArrayList<>(Arrays.asList(R.drawable.home_control,R.drawable.home_navigation,R.drawable.home_media, ? ? ? ? ? ? ? ? R.drawable.home_hvac,R.drawable.home_energy,R.drawable.home_account,R.drawable.home_iot)); ? ? } ? ? /** ? ? ?* ? ? ?* @param view ?執(zhí)行動(dòng)畫的view ? ? ?* @param from ?幅度最大值 ? ? ?* @param to ? ?結(jié)束值 ? ? ?* @param tension ?張力 ? ? ?* @param friction 摩擦力(值越小 彈的次數(shù)越多 ?0為無限循環(huán) 參考值 4) ? ? ?*/ ? ? private void springAnim(final View view,float from,float to,double tension,double friction){ ? ? ? ? SpringSystem system = SpringSystem.create(); ? ? ? ? Spring spring = system.createSpring(); ? ? ? ? spring.setCurrentValue(from); ? ? ? ? spring.setSpringConfig(new SpringConfig(tension, friction)); ? ? ? ? spring.addListener(new SimpleSpringListener(){ ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onSpringUpdate(Spring spring) { ? ? ? ? ? ? ? ? view.setTranslationX((float) spring.getCurrentValue()); ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? spring.setEndValue(to); ? ? } }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android?ScrollView實(shí)現(xiàn)滾動(dòng)超過邊界松手回彈
- android ScrollView實(shí)現(xiàn)水平滑動(dòng)回彈
- Android實(shí)現(xiàn)背景圖滑動(dòng)變大松開回彈效果
- Android實(shí)現(xiàn)橡皮筋回彈和平移縮放效果
- Android自定義View實(shí)現(xiàn)豎向滑動(dòng)回彈效果
- android實(shí)現(xiàn)可上下回彈的scrollview
- Android實(shí)現(xiàn)回彈ScrollView的原理
- Android自定義實(shí)現(xiàn)可回彈的ScollView
- Android ScrollView的頂部下拉和底部上拉回彈效果
- android自定義滾動(dòng)上下回彈scollView
相關(guān)文章
如何使用SurfaceView實(shí)現(xiàn)魚兒游動(dòng)動(dòng)畫
這篇文章主要教大家如何使用SurfaceView實(shí)現(xiàn)魚兒游動(dòng)動(dòng)畫,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04Android實(shí)戰(zhàn)教程第四十篇之Chronometer實(shí)現(xiàn)倒計(jì)時(shí)
這篇文章主要介紹了Android實(shí)戰(zhàn)教程第四十篇之Chronometer實(shí)現(xiàn)倒計(jì)時(shí),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11Android ViewPager循環(huán)播放廣告實(shí)例詳解
這篇文章主要介紹了Android ViewPager循環(huán)播放廣告條實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-03-03Android軟鍵盤的顯示隱藏功能實(shí)現(xiàn)過程
這篇文章主要介紹了Android軟鍵盤的顯示隱藏功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-03-03Android實(shí)現(xiàn)圓形圖片或者圓角圖片
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)圓形圖片或者圓角圖片的代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06Android開發(fā)者需要知道的8個(gè)項(xiàng)目管理技巧
這篇文章主要為大家詳細(xì)介紹了Android開發(fā)者需要知道的8個(gè)項(xiàng)目管理技巧,感興趣的小伙伴們可以參考一下2016-02-02Android判斷網(wǎng)絡(luò)狀態(tài)的代碼
這篇文章主要為大家詳細(xì)介紹了Android判斷網(wǎng)絡(luò)狀態(tài)的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10Android 實(shí)現(xiàn)獲取手機(jī)里面的所有圖片詳解及實(shí)例
這篇文章主要介紹了Android 實(shí)現(xiàn)獲取手機(jī)里面的所有圖片詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-05-05