杂货铺(RecyclerView,SpannableString,ViewAnimationUtils.createCircularReveal()动画)

     忙而充实,总结一下今天学到的以及之前感觉很好用的小知识点。

1.ViewAnimationUtils.createCircularReveal()动画

ViewAnimationUtils.createCircularReveal()动画Android L引进到Android中的,此动画是能够实现圆形快速切换,属于Google  Material Design风格的动画。

注意:此方法只能在Android L及其以上使用,再Android L 以下不能使用该方法 使用会报异常。

使用方法:

第一步:从A页面设置调转B页面

 lv.setOnItemClickListener(new RecyclerAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(int position, Object object) {
                Intent intent = new Intent();
                intent.setClass(MainActivity.this, NextActivity.class);
                startActivity(intent);
            }
        });

第二步:B页面布局,建议设置背景比较明显的来添加动画,这样效果比较好

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rl"
    android:background="@mipmap/a"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <ImageView
        android:id="@+id/pic"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="TextView"
        android:textSize="25sp" />
</RelativeLayout>

第三步:在B页面添加如下代码,此处添加了沉浸式这样效果会好一点,设置这个动画建议背景明显的布局使用效果很明显。

public class NextActivity extends Activity {
    private RelativeLayout rl;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //透明状态栏
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        //透明导航栏
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        setContentView(R.layout.item_card_view);
        rl = (RelativeLayout) findViewById(R.id.rl);
        rl.post(new Runnable() {
            @Override
            public void run() {
                // 圆形动画的x坐标  位于View的中心
                int cx = (rl.getLeft() + rl.getRight()) / 2;

                //圆形动画的y坐标  位于View的中心
                int cy = (rl.getTop() + rl.getBottom()) / 2;

                //起始大小半径
                float startX = 0f;

                //结束大小半径 大小为图片对角线的一半
                float startY = (float) Math.sqrt(cx * cx + cy * cy);
                Animator animator = ViewAnimationUtils.createCircularReveal(rl, cx, cy, startX, startY);
                //在动画开始的地方速率改变比较慢,然后开始加速
                animator.setInterpolator(new AccelerateInterpolator());
                animator.setDuration(600);
                animator.start();
            }
        });
    }
}

2.SpannableString实现TextView不同的指定文字拥有不同的点击事件。

举个栗子:微信朋友圈某条说说如下图,点击任意人名跳转到他的个人主页。

代码如下:(懒得直接从用的当中拷贝了,期间我会标注的事重点,其他的代码大家可以忽略,这里做的效果就如上图)

 zanNames = data.getLikenames().toString().split(",");//我得到的点赞人是String字符串用逗号隔开的,所以在之前用逗号将字符串截取成为一个String集合

 for (int i = 0; i < data.getLikenames().length(); i++) {
                    if (data.getLikenames().charAt(i) == ',') {
                        dotLocations.add(i);
                    }
                }//这里得到点的位置,为后续区分点击的事哪一个名字做准备
                int end = 0;
                int start = 0;
                SpannableString str = new SpannableString(data.getLikenames().toString());//重点开始了
                for (int i = 0; i < zanNames.length; i++) {
                    if (zanNames.length - 1 == 0) {
                        start = 0;
                        end = 0 + zanNames[i].length();
                    } else {
                        if (i == 0) {
                            start = 0;
                            end = dotLocations.get(i) - 1;
                        } else if (i == zanNames.length - 1) {
                            start = end + 2;
                            end = start + zanNames[i].length();
                        } else {
                            start = end + 2;
                            end = dotLocations.get(i) - 1;
                        }
                    }
                    str.setSpan(new MyClickableSpan(position,i), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);//这里为每一个名字设置监听,如果一个就可以直接写为匿名内部类,但是如果像我这样循环的话一定要new一个实现类,否则会被覆盖只有一个名字可以正确的调转其他的都只会跳转到最后一个名字的主页。
                    vh.zanNames.setMovementMethod(LinkMovementMethod.getInstance());//不设置 没有点击事件
                    vh.zanNames.setText(str);
                }

 

 class MyClickableSpan extends ClickableSpan {
        private int position,id;
        public MyClickableSpan(int position,int finalI) {
            this.position = position;
            this.id=finalI;
        }
        @Override
        public void onClick(View widget) {//点击后要做的事
            zanIds = list.get(position).getUserIds().toString().split(",");
            Intent intent = new Intent(context, PersonalShowActivity.class);
            intent.putExtra("userId", Integer.parseInt(zanIds[id]));
            context.startActivity(intent);
        }

        @Override
        public void updateDrawState(TextPaint ds) {//这里是改变字的样式的,如果不添加会显示系统默认的绿色加下划线的样式
            super.updateDrawState(ds);
            //设置文本的颜色#576b95
            ds.setColor(context.getResources().getColor(R.color.zanname));
            //超链接形式的下划线,false 表示不显示下划线,true表示显示下划线
            ds.setUnderlineText(false);
        }
    }

今天一个大神朋友也推荐SpannableString,看来是真的很好用,大家有时间还可以来看看它的其他用法,比如改变其中某些字体的颜色,这个我在之前的文章中写过,大家感兴趣可以找找。

3.RecyclerView

今天被之前同事的代码坑的好惨,他们使用的listview框架是很老很不好意的那种,然后他走了,他的bug就归我了,心塞。今天的bug是关于刷新的事。比如微信朋友圈你加载了八页数据,在第五页评论了一条说说,然后因为各种原因你只能通过刷新数据来展示你刚刚评论的内容,这里就需要你刷新所有的数据再回到第五页你评论的这条说说。然而这个老框架并没有setSelectionFromTop这个方法,朋友推荐了RecyclerView,bug改的很牵强,然后就挤时间用了一下RecyclerView。讲真,真心好用,但是以前项目中没有用也就懒得没写过demo。

第一步:

引用Support v7包,在AS里很好配置,直接在build.gradle文件下添加如下配置:

第二步:

第三步:

setLayoutManager()方法接受一个 LayoutManager 布局管理参数。参数类型可以有以下几种:

LinearLayoutManager:线性布局

GridLayoutManager:网格布局

StaggeredGridLayoutManager:流式布局

那么怎么new一个LayoutManager出来呢?举个例子:

new LinearLayoutManager(this, LinearLayout.VERTICAL, true)

第一个参数 Context ,第二个参数:布局方向LinearLayout.VERTICAL垂直和LinearLayout.HORIZONTAL水平,第三个参数:表示是否从最后的Item数据开始显示,ture表示是,false就是正常显示—从开头显示。

setItemAnimator()方法的作用是设置当前RecyclerView容器有子Item改变时(添加item或者删除item)导致整个布局的动画效果。一般我们new 一个系统默认的动画出来就好了。

第四步:

我们是继承RecyclerView.Adapter类,实现里面的抽象方法即可。可以看到RecyclerView.Adapter适配器里面有一套完整的机制来控制之ItemView的查找和显示。通过内部类MyViewHolder继承RecyclerView.ViewHolder封装容器中的ItemView,实现onCreateViewHolder抽象方法来加载ItemView的布局,实现onBindViewHolder抽象方法来绑定容器中的ItemView,进而进行赋值。

第五步:

细心的你会发现,很遗憾的是RecyclerView没有提供setItemOnClickListener点击监听方法。那么我们要监听每个ItemView的点击事件怎么办呢?没关系!我们来看看代码中怎么实现吧!

在RecyclerView的适配器类中定义了一个OnItemClickListener接口,然后在onBindViewHolder方法中设置每个holder.itemView的点击事件,外面调用setOnItemClickListener方法即可。

RecyclerView添加,删除,更新数据

和ListView,GridView容器不一样的是,RecyclerView容器更新数据的方法有很多:

notifyDataSetChanged():更新所有数据
notifyItemInserted(int position):在position位置插入数据的时候更新
notifyItemRemoved(int position):移除postion位置的数据的时候更新
notifyItemChanged(int position):当postion位置数据有改变时候更新
notifyItemMoved(int fromPosition, int toPosition):移除从位置formPosition到toPosition位置数据更新
notifyItemRangeChanged(int positionStart, int itemCount)
notifyItemRangeInserted(int positionStart, int itemCount)
notifyItemRangeRemoved(int positionStart, int itemCount)

如果你在代码里设置了RecyclerView的ItemView改变时有动画效果的话

recylerView.setItemAnimator(new DefaultItemAnimator());

4.解决错误日志Error:java.lang.RuntimeException: Some file crunching failed, see logs for details

出现这个错误的原因是有哪种情况?
1.构建Gradle的时候,Gradle会去检查一下是否修改过文件的后缀名;
2.一般大多数是出现在图片上,.jpg修改成了.png就会出现这个问题;
3.9patch图片也可能出现这个问题。

解决方式就是在在项目的gradle加入红圈圈起的即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值