标签: Adapter

android添加购物车动画 参考

android添加购物车动画实现

%title插图%num

商品列表Adapter

  1. import android.content.Context;
  2. import android.graphics.drawable.Drawable;
  3. import android.view.LayoutInflater;
  4. import android.view.View;
  5. import android.view.ViewGroup;
  6. import android.widget.BaseAdapter;
  7. import android.widget.Button;
  8. import android.widget.ImageView;
  9. import android.widget.LinearLayout;
  10. /**
  11. * 商品列表Adapter
  12. * @author antkingwei
  13. *
  14. */
  15. public class GoodAdapter extends BaseAdapter{
  16. private Context mContext;
  17. private LayoutInflater layoutInflater;
  18. private HolderClickListener mHolderClickListener;
  19. final class ViewHolder {
  20. ImageView imgview;
  21. Button button;
  22. }
  23. public GoodAdapter(Context context){
  24. this.mContext = context;
  25. layoutInflater = LayoutInflater.from(mContext);
  26. }
  27. @Override
  28. public int getCount() {
  29. // TODO Auto-generated method stub
  30. return 16;
  31. }
  32. @Override
  33. public Object getItem(int position) {
  34. // TODO Auto-generated method stub
  35. return null;
  36. }
  37. @Override
  38. public long getItemId(int position) {
  39. // TODO Auto-generated method stub
  40. return position;
  41. }
  42. @Override
  43. public View getView(int position, View convertView, ViewGroup parent) {
  44. // TODO Auto-generated method stub
  45. final int selectedId = position;
  46. final ViewHolder viewHolder;
  47. if(convertView ==null){
  48. viewHolder = new ViewHolder();
  49. convertView = layoutInflater.inflate(R.layout.adapter_listview, null);
  50. viewHolder.imgview = (ImageView)convertView.findViewById(R.id.item_img);
  51. viewHolder.button = (Button)convertView.findViewById(R.id.item_button);
  52. convertView.setTag(viewHolder);
  53. }else{
  54. viewHolder =(ViewHolder)convertView.getTag();
  55. }
  56. viewHolder.button.setOnClickListener(new View.OnClickListener() {
  57. @Override
  58. public void onClick(View v) {
  59. // TODO Auto-generated method stub
  60. if(mHolderClickListener!=null){
  61. int[] start_location = new int[2];
  62. viewHolder.imgview.getLocationInWindow(start_location);//获取点击商品图片的位置
  63. Drawable drawable = viewHolder.imgview.getDrawable();//复制一个新的商品图标
  64. mHolderClickListener.onHolderClick(drawable,start_location);
  65. }
  66. }
  67. });
  68. return convertView;
  69. }
  70. public void SetOnSetHolderClickListener(HolderClickListener holderClickListener){
  71. this.mHolderClickListener = holderClickListener;
  72. }
  73. public interface HolderClickListener{
  74. public void onHolderClick(Drawable drawable,int[] start_location);
  75. }
  76. }

活动类

  1. package com.example.addshopcart;
  2. import com.example.addshopcart.GoodAdapter.HolderClickListener;
  3. import android.os.Bundle;
  4. import android.os.Handler;
  5. import android.os.Message;
  6. import android.app.Activity;
  7. import android.content.Context;
  8. import android.graphics.drawable.Drawable;
  9. import android.view.Menu;
  10. import android.view.View;
  11. import android.view.ViewGroup;
  12. import android.view.animation.Animation;
  13. import android.view.animation.Animation.AnimationListener;
  14. import android.view.animation.AnimationSet;
  15. import android.view.animation.RotateAnimation;
  16. import android.view.animation.ScaleAnimation;
  17. import android.view.animation.TranslateAnimation;
  18. import android.widget.Button;
  19. import android.widget.FrameLayout;
  20. import android.widget.ImageView;
  21. import android.widget.ListView;
  22. /**
  23. *
  24. * @author antkingwei
  25. *
  26. */
  27. public class MainActivity extends Activity {
  28. private ListView listView;
  29. private Button cart_btn;
  30. private GoodAdapter goodAdapter;
  31. //动画时间
  32. private int AnimationDuration = 1000;
  33. //正在执行的动画数量
  34. private int number = 0;
  35. //是否完成清理
  36. private boolean isClean = false;
  37. private FrameLayout animation_viewGroup;
  38. private Handler myHandler = new Handler(){
  39. public void handleMessage(Message msg){
  40. switch(msg.what){
  41. case 0:
  42. //用来清除动画后留下的垃圾
  43. try{
  44. animation_viewGroup.removeAllViews();
  45. }catch(Exception e){
  46. }
  47. isClean = false;
  48. break;
  49. default:
  50. break;
  51. }
  52. }
  53. };
  54. @Override
  55. protected void onCreate(Bundle savedInstanceState) {
  56. super.onCreate(savedInstanceState);
  57. setContentView(R.layout.activity_main);
  58. listView = (ListView)this.findViewById(R.id.listview);
  59. cart_btn = (Button)this.findViewById(R.id.button);
  60. animation_viewGroup = createAnimLayout();
  61. goodAdapter = new GoodAdapter(this);
  62. goodAdapter.SetOnSetHolderClickListener(new HolderClickListener(){
  63. @Override
  64. public void onHolderClick(Drawable drawable,int[] start_location) {
  65. // TODO Auto-generated method stub
  66. doAnim(drawable,start_location);
  67. }
  68. });
  69. listView.setAdapter(goodAdapter);
  70. }
  71. private void doAnim(Drawable drawable,int[] start_location){
  72. if(!isClean){
  73. setAnim(drawable,start_location);
  74. }else{
  75. try{
  76. animation_viewGroup.removeAllViews();
  77. isClean = false;
  78. setAnim(drawable,start_location);
  79. }catch(Exception e){
  80. e.printStackTrace();
  81. }
  82. finally{
  83. isClean = true;
  84. }
  85. }
  86. }
  87. /**
  88. * @Description: 创建动画层
  89. * @param
  90. * @return void
  91. * @throws
  92. */
  93. private FrameLayout createAnimLayout(){
  94. ViewGroup rootView = (ViewGroup)this.getWindow().getDecorView();
  95. FrameLayout animLayout = new FrameLayout(this);
  96. FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,FrameLayout.LayoutParams.MATCH_PARENT);
  97. animLayout.setLayoutParams(lp);
  98. animLayout.setBackgroundResource(android.R.color.transparent);
  99. rootView.addView(animLayout);
  100. return animLayout;
  101. }
  102. /**
  103. * @deprecated 将要执行动画的view 添加到动画层
  104. * @param vg
  105. * 动画运行的层 这里是frameLayout
  106. * @param view
  107. * 要运行动画的View
  108. * @param location
  109. * 动画的起始位置
  110. * @return
  111. */
  112. private View addViewToAnimLayout(ViewGroup vg,View view,int[] location){
  113. int x = location[0];
  114. int y = location[1];
  115. vg.addView(view);
  116. FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
  117. dip2px(this,90),dip2px(this,90));
  118. lp.leftMargin = x;
  119. lp.topMargin = y;
  120. view.setPadding(5, 5, 5, 5);
  121. view.setLayoutParams(lp);
  122. return view;
  123. }
  124. /**
  125. * dip,dp转化成px 用来处理不同分辨路的屏幕
  126. * @param context
  127. * @param dpValue
  128. * @return
  129. */
  130. private int dip2px(Context context,float dpValue){
  131. float scale = context.getResources().getDisplayMetrics().density;
  132. return (int)(dpValue*scale +0.5f);
  133. }
  134. /**
  135. * 动画效果设置
  136. * @param drawable
  137. * 将要加入购物车的商品
  138. * @param start_location
  139. * 起始位置
  140. */
  141. private void setAnim(Drawable drawable,int[] start_location){
  142. Animation mScaleAnimation = new ScaleAnimation(1.5f,0.0f,1.5f,0.0f,Animation.RELATIVE_TO_SELF,0.1f,Animation.RELATIVE_TO_SELF,0.1f);
  143. mScaleAnimation.setDuration(AnimationDuration);
  144. mScaleAnimation.setFillAfter(true);
  145. final ImageView iview = new ImageView(this);
  146. iview.setImageDrawable(drawable);
  147. final View view = addViewToAnimLayout(animation_viewGroup,iview,start_location);
  148. view.setAlpha(0.6f);
  149. int[] end_location = new int[2];
  150. cart_btn.getLocationInWindow(end_location);
  151. int endX = end_location[0];
  152. int endY = end_location[1]-start_location[1];
  153. Animation mTranslateAnimation = new TranslateAnimation(0,endX,0,endY);
  154. Animation mRotateAnimation = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
  155. mRotateAnimation.setDuration(AnimationDuration);
  156. mTranslateAnimation.setDuration(AnimationDuration);
  157. AnimationSet mAnimationSet = new AnimationSet(true);
  158. mAnimationSet.setFillAfter(true);
  159. mAnimationSet.addAnimation(mRotateAnimation);
  160. mAnimationSet.addAnimation(mScaleAnimation);
  161. mAnimationSet.addAnimation(mTranslateAnimation);
  162. mAnimationSet.setAnimationListener(new AnimationListener(){
  163. @Override
  164. public void onAnimationStart(Animation animation) {
  165. // TODO Auto-generated method stub
  166. number++;
  167. }
  168. @Override
  169. public void onAnimationEnd(Animation animation) {
  170. // TODO Auto-generated method stub
  171. number–;
  172. if(number==0){
  173. isClean = true;
  174. myHandler.sendEmptyMessage(0);
  175. }
  176. }
  177. @Override
  178. public void onAnimationRepeat(Animation animation) {
  179. // TODO Auto-generated method stub
  180. }
  181. });
  182. view.startAnimation(mAnimationSet);
  183. }
  184. /**
  185. * 内存过低时及时处理动画产生的未处理冗余
  186. */
  187. @Override
  188. public void onLowMemory() {
  189. // TODO Auto-generated method stub
  190. isClean = true;
  191. try{
  192. animation_viewGroup.removeAllViews();
  193. }catch(Exception e){
  194. e.printStackTrace();
  195. }
  196. isClean = false;
  197. super.onLowMemory();
  198. }
  199. @Override
  200. public boolean onCreateOptionsMenu(Menu menu) {
  201. // Inflate the menu; this adds items to the action bar if it is present.
  202. getMenuInflater().inflate(R.menu.main, menu);
  203. return true;
  204. }
  205. }

activity_main.xml

  1. <RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”
  2. xmlns:tools=“http://schemas.android.com/tools”
  3. android:layout_width=“match_parent”
  4. android:layout_height=“match_parent”
  5. android:paddingBottom=“@dimen/activity_vertical_margin”
  6. android:paddingLeft=“@dimen/activity_horizontal_margin”
  7. android:paddingRight=“@dimen/activity_horizontal_margin”
  8. android:paddingTop=“@dimen/activity_vertical_margin”
  9. tools:context=“.MainActivity” >
  10. <ListView
  11. android:layout_width=“match_parent”
  12. android:layout_height=“match_parent”
  13. android:id=“@+id/listview”
  14. ></ListView>
  15. <Button
  16. android:layout_alignBottom=“@+id/listview”
  17. android:layout_centerHorizontal=“true”
  18. android:layout_width=“wrap_content”
  19. android:layout_height=“wrap_content”
  20. android:id=“@+id/button”
  21. android:text=“购物车”
  22. />
  23. </RelativeLayout>

AdapterItem布局

  1. <?xml version=”1.0″ encoding=”utf-8″?>
  2. <RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”
  3. android:layout_width=“match_parent”
  4. android:layout_height=“match_parent”
  5. >
  6. <ImageView
  7. android:id=“@+id/item_img”
  8. android:layout_width=“wrap_content”
  9. android:layout_height=“wrap_content”
  10. android:src=“@drawable/ic_launcher”
  11. android:layout_alignParentLeft=“true”
  12. />
  13. <Button
  14. android:id=“@+id/item_button”
  15. android:layout_width=“wrap_content”
  16. android:layout_height=“wrap_content”
  17. android:layout_alignParentRight=“true”
  18. android:text=“添加”
  19. >
  20. </Button>
  21. </RelativeLayout>

请教下 ViewModel 和 Adapter 该如何结合以实现动态加载

如题,我的 ViewModel 类中有一个列表结构的数据,需要动态加载,代码如下:

class TimelineViewModel : ViewModel() {
    val timelines = MutableLiveData<List<TimelineModel>>(emptyList())

    private var nextTime = System.currentTimeMillis()

    fun getTimeline() {
    	viewModelScope.launch {
            try {
                val respData = Repository.getTimeline(nextTime)
                if (respData.data != null) {
                    nextTime = respData.data.feeds.nextTime
                    val timelineModels = respData.data.feeds.data.filterNotNull().map {
                        TimelineModel(it)
                    }
                    timelines.value = timelines.value.let {
                        if (it == null) {
                            timelineModels
                        } else {
                            it + timelineModels
                        }
                    }
                }
            } catch (e: Exception) {
                Log.e(TAG, "Network Request Fail", e)
            }
        }
    }
}
  • 如果在视图层直接使用 MutableLiveData#observe 方法观察这个数据,那么观察到的是整个 List 数据的变化,那么该怎么将其转化为 Adapter 的添加元素的行为?
  • 或者应该怎么处理这种需要修改列表数据的场景?

nexttime

val

viewmodel

lue

3 条回复    2021-08-24 19:57:24 +08:00

omysho
    1

omysho   15 天前 via Android   ❤️ 1

有个东西叫 DiffUtil

还有个东西叫 AsyncListDiffer

还有个东西叫 ListAdapter 继承自 Recycler.Adapter 需要一个 ItemDiffCallback 作为构造参数

pigspy
    2

pigspy   15 天前

@omysho

非常感谢

122006
    3

122006   5 天前

androidx 的 recycleview 自带,直接继承 listadapter 就行
友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速