博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
开源app之MyHearts
阅读量:4641 次
发布时间:2019-06-09

本文共 8711 字,大约阅读时间需要 29 分钟。

前言

这个月,说实话,有忙有闲,经历了一次病痛的洗礼,才认识到了只有好好的生活,认真的对待自己的身体,才能更好的去工作,没有了身体的支撑,什么工作都只能是纸老虎,不攻自破。在这里也祝愿大家,在生活中好好对待自己,身体第一,工作第二。

为什么要写这个app

群里的一个哥们前几天晚上给我看了一下一个app,我粗略看了下界面(还没运行下载,他给我发的),我看了一下,感觉挺不错的,当时心里一热,哈哈,这不是挺简单的么,几天就搞完了,但是当我去下载的时候,看到了30-40MB的大小,我惊呆了,要知道一个淘宝才那么大。哈哈,不过还是被这个界面吸引了,而且里面的内容也挺不错的,大多关于心理方面的。那就自己模仿一下吧,顺带的自己去学习一下,因为这个app涉及到的知识点挺多(即时通讯、直播、视屏播放、第三方登录),想着自己就慢慢的写,然后去学习一下会用到的知识,伴随着这样的想法,就有了这个MyHearts项目。

几个小知识点

一、进入到主界面,可以看到下方的几个Tab键,原本想着是用FragmentTabhost实现,但是看到中间的那个Tab键和其他的按键是不同等高度的,而且这个还是有动画效果的,后面想着,如果用framelayout覆盖在上面应该是可以实现的,但是动画呢,这个时候想到之前用到的帧动画,想必这个帧动画也是可以实现的,然后自己就去试了试,结果还真给实现了,对于程序这东西来说,当别人问这个能不能实现,我在这个地方加一个字段、加个方法,可以实现么,我想说的就是,既然已经想到了,那就试一下呗,行了就证明方法可以,不行证明需要找其他的方法,最重要的是动手写程序,程序不是问出来的,而是一句一句代码积累出来的。

//这里并没有写完,可以直接去代码里面查看,最后会附上git地址

在代码中这样就可以执行动画了

// 获取ImageView上的动画背景        AnimationDrawable spinnerImg = (AnimationDrawable) mIvImg.getBackground();        // 开始动画        spinnerImg.start();

这样就可以实现直播和life动画的切换了。

二、心事界面的图片展示,之前在用postman(用于接口调试的,值得推荐)请求数据接口的时候,看到里面有个photos字段,并不是所有的item都有这个字段,而且里面个数不一,但都是一个图片地址,想着应该是类似于qq空间发表说说的附带的图片。自己想着用RecyclerView实现,因为这个是很好实现的,但是我在看到okgo(本项目的网络请求框架,支持Rx,挺不错的)项目中,他的项目也有这个类似的功能,用到的就是NineGridView(这个项目也是这位大神写的。这个也是很简单使用的,他是在ViewGroup的基础上自定义的。用法也是很简单,如下

//也就是用户发朋友圈的那种,添加图片        List
images = bean.getPhotos(); if (images != null) { for (String image : images) { //ImageInfo 是他的实体类,用于image的地址 ImageInfo info = new ImageInfo(); info.setThumbnailUrl(image); info.setBigImageUrl(image); imageInfo.add(info); } } holder.mPhotoRecycler.setAdapter(new NineGridViewClickAdapter(mContext, imageInfo)); if (images != null && images.size() == 1) { //如果用户只发了一张图片的话,就设置图片的宽和高 holder.mPhotoRecycler.setSingleImageSize(300); holder.mPhotoRecycler.setSingleImageRatio(1); //holder.mPhotoRecycler.setSingleImageRatio(images.get(0).width * 1.0f / images.get(0).height); }

实现的结果如下:

三、二级评论列表,这个我一直想不到好的解决办法(在我脑海里一直以为有更好的方法),这里我就是用的item里面嵌套一个RecyclerView,得到的comment list,然后在进行item分配。如果有好的,请告知。谢谢啦。

这里就看下代码,也没什么可写的,无非就是RecyclerView嵌套RecyclerView

List
comments = bean.getComments(); if (comments != null && comments.size() > 0) { CommentAdapter adapter = new CommentAdapter(comments); holder.mCommentRe.setVisibility(View.VISIBLE); holder.mCommentRecycler.setLayoutManager(new LinearLayoutManager(mContext)); // holder.mCommentRecycler.addItemDecoration(new DividerItemDecoration(mContext //,DividerItemDecoration.VERTICAL_LIST)); holder.mCommentRecycler.setItemAnimator(new DefaultItemAnimator()); holder.mCommentRecycler.setAdapter(adapter); }

对于评论里面的回复和被回复者,为了便于区分,我这里使用到了SpanableString。类似于下面:

CommentsBean bean = mCommentsBeen.get(position);            //评论用户            String profileName = bean.getName();            //被回复者  如果为空  默认回复发帖者            String replayName = bean.getReplyToUserName();            StringBuffer sb = new StringBuffer();            sb.append(profileName);            sb.append(" ");            String replay = mContext.getResources().getString(R.string.replay_comment);            if (!replayName.equals("")) {  //判断是否有被回复的,没有就是默认发帖者                sb.append(replay);                sb.append(replayName);            }            String commentContent = bean.getContent();            sb.append(commentContent);           // String result = ;            SpannableString msp = new SpannableString(sb.toString());            //对评论者进行颜色配置            msp.setSpan(new ForegroundColorSpan(Color.BLUE), 0,                    profileName.length(),                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);            //如果有被回复的对象,那么被回复的对象也要进行颜色配置            if (!replayName.equals("")) {                int start = profileName.length() + 3;                int end = start + replayName.length();                msp.setSpan(new ForegroundColorSpan(Color.BLUE), start, end,                        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);            }            //这个地方要直接设置成msp  不能用msp.toString() 要不然没有样式            holder.mTvCommentContent.setText(msp);

效果图,大家可以git代码去运行一下。

四、之前用到左滑出菜单栏,第一个是Draglayout,但是这个存在冲突,滑动不是很流畅,自己后面换到了git上的一个仿QQ5.2的,但是和自己app里面的轮播(从左向右滑动的时候,会带出左侧边栏,还有就是心事界面的Tablayout也是存在同样的方式,后面自己想到了应该是用到的ViewPager滑动事件的问题,就想着之前用到的,就重写了ViewPager,然后处理了一些逻辑,基本解决了冲突),代码如下:

/**     * 事件分发,请求父控件是否拦截     * 

* 1、右滑,而且是第一个页面,需要父控件拦截 *

* 2、左滑,而且当前的页面是最后一个页面,需要父控件拦截 *

* 3、上下滑动,需要父控件拦截 * * @param ev * @return */ @Override public boolean dispatchTouchEvent(MotionEvent ev) { /** * 用getParent()去请求,请求父控件是否不要拦截滑动事件 */ switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: //先去让父控件不要拦截,这样才可能走到ACTION_MOVE方法调用 getParent().requestDisallowInterceptTouchEvent(true); /** * 拿到刚开始按下的时候的坐标 */ startX = (int) ev.getRawX(); startY = (int) ev.getRawY(); break; case MotionEvent.ACTION_MOVE: /** * 获取到移动之后的坐标 */ int endX = (int) ev.getRawX(); int endY = (int) ev.getRawY(); //左右滑动 if (Math.abs(endX - startX) > Math.abs(endY - startY)) { if (endX > startX) { //右滑 //获取到第一个 需要父控件拦截 if (getCurrentItem() == 0) { getParent().requestDisallowInterceptTouchEvent(false); } } else if (endX <= startX) { //左滑 //获取到最后一个 // 需要父控件拦截 if (getCurrentItem() == getAdapter().getCount() - 1) { getParent().requestDisallowInterceptTouchEvent(false); } } } else { //上下滑动 getParent().requestDisallowInterceptTouchEvent(false); } break; default: break; } return super.dispatchTouchEvent(ev); }

哈哈,最后还是换成了DrawerLayout,不存在了滑动的冲突BUG了,Drawerlayout默认划出是覆盖在主界面上的,这里为了模仿的比较像,就重写了一些逻辑(hongyang大神的博客中有介绍)

mDrawerLayout.setDrawerListener(new DrawerLayout.DrawerListener() {            @Override            public void onDrawerSlide(View drawerView, float slideOffset) {                View mContent = mDrawerLayout.getChildAt(0);                View mMenu = drawerView;                float scale = 1 - slideOffset;                float rightScale = 0.8f + scale * 0.2f;                if (drawerView.getTag().equals("LEFT"))                {                    float leftScale = 1 - 0.3f * scale;                    ViewHelper.setScaleX(mMenu, leftScale);                    ViewHelper.setScaleY(mMenu, leftScale);                    ViewHelper.setAlpha(mMenu, 0.6f + 0.4f * (1 - scale));                    ViewHelper.setTranslationX(mContent,                            mMenu.getMeasuredWidth() * (1 - scale));                    ViewHelper.setPivotX(mContent, 0);                    ViewHelper.setPivotY(mContent,                            mContent.getMeasuredHeight() / 2);                    mContent.invalidate();                    ViewHelper.setScaleX(mContent, rightScale);                    ViewHelper.setScaleY(mContent, rightScale);                } else                {                    ViewHelper.setTranslationX(mContent,                            -mMenu.getMeasuredWidth() * slideOffset);                    ViewHelper.setPivotX(mContent, mContent.getMeasuredWidth());                    ViewHelper.setPivotY(mContent,                            mContent.getMeasuredHeight() / 2);                    mContent.invalidate();                    ViewHelper.setScaleX(mContent, rightScale);                    ViewHelper.setScaleY(mContent, rightScale);                }            }            @Override            public void onDrawerOpened(View drawerView) {            }            @Override            public void onDrawerClosed(View drawerView) {                mDrawerLayout.setDrawerLockMode(                        DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.RIGHT);            }            @Override            public void onDrawerStateChanged(int newState) {            }        });

到这里,基本上就没什么知识点了(因为自己也写的不是很好,加上自己的水平有限),后面增加新功能了在做补充。

最后上传几张效果图:

代码传送门(如果感觉还不错,欢迎star下)

转载于:https://www.cnblogs.com/android-blogs/p/6006598.html

你可能感兴趣的文章
面向对象1
查看>>
编程开发之--java多线程学习总结(5)
查看>>
register_globals(全局变量注册开关)
查看>>
as3调用外部swf里的类的方法
查看>>
如何让 zend studio 10 识别 Phalcon语法并且进行语法提示
查看>>
任意阶幻方(魔方矩阵)C语言实现
查看>>
视频教程--ASP.NET MVC 使用 Petapoco 微型ORM框架+NpgSql驱动连接 PostgreSQL数据库
查看>>
第五次作业
查看>>
织梦教程
查看>>
杭电多校 Harvest of Apples 莫队
查看>>
java 第11次作业:你能看懂就说明你理解了——this关键字
查看>>
C/C++心得-结构体
查看>>
函数名作为参数传递
查看>>
apt-get for ubuntu 工具简介
查看>>
数值计算算法-多项式插值算法的实现与分析
查看>>
day8-异常处理与网络编程
查看>>
Python基础-time and datetime
查看>>
Linux epoll 笔记(高并发事件处理机制)
查看>>
shell脚本练习01
查看>>
WPF图标拾取器
查看>>