开源app之MyHearts

前言

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

为什么要写这个app

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

几个小知识点

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

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"android:oneshot="false"><itemandroid:drawable="@mipmap/main_layout_center_image_1"android:duration="100"/><itemandroid:drawable="@mipmap/main_layout_center_image_2"android:duration="100"/><itemandroid:drawable="@mipmap/main_layout_center_image_3"android:duration="100"/><itemandroid:drawable="@mipmap/main_layout_center_image_4"android:duration="100"/><itemandroid:drawable="@mipmap/main_layout_center_image_5"android:duration="100"/><itemandroid:drawable="@mipmap/main_layout_center_image_6"android:duration="100"/><itemandroid:drawable="@mipmap/main_layout_center_image_7"android:duration="100"/><itemandroid:drawable="@mipmap/main_layout_center_image_8"android:duration="100"/><itemandroid:drawable="@mipmap/main_layout_center_image_9"android:duration="100"/>//这里并没有写完,可以直接去代码里面查看,最后会附上git地址</animation-list>

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

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

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

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

 //也就是用户发朋友圈的那种,添加图片List<String> 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<CommentsBean> 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,然后处理了一些逻辑,基本解决了冲突),代码如下:

/*** 事件分发,请求父控件是否拦截* <p/>* 1、右滑,而且是第一个页面,需要父控件拦截* <p/>* 2、左滑,而且当前的页面是最后一个页面,需要父控件拦截* <p/>* 3、上下滑动,需要父控件拦截** @param ev* @return*/@Overridepublic 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() {@Overridepublic 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);}}@Overridepublic void onDrawerOpened(View drawerView) {}@Overridepublic void onDrawerClosed(View drawerView) {mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.RIGHT);}@Overridepublic void onDrawerStateChanged(int newState) {}});

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



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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/457061.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于在软件中添加扫描二维码功能的详细步骤及对应的资源。

最近有在一款软件中添加二维码扫描功能&#xff0c;在网上整理了一堆资源后&#xff0c;把一些干货拿出来给大家分享&#xff0c;希望大家以后能更容易的使用这个功能。 详细步骤见这个视频连接&#xff1a;http://www.jikexueyuan.com/course/134.html 对应的zxing资源放在下…

前端那些事之原生 js实现贪吃蛇篇

2019独角兽企业重金招聘Python工程师标准>>> 原生js实现贪吃蛇 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>贪吃蛇游戏</title><style>body, div, img {margin: 0 auto;pa…

整理一些完全免费开放的API接口

前言 在开发测试阶段&#xff0c;或者是在写Demo的时候&#xff0c;难免会用到一些测试数据&#xff0c;有时苦于没有可用的接口&#xff0c;需要自己动手去写&#xff0c;但是这样大大降低了效率&#xff0c;前期我也找了一些开放的接口&#xff0c;这篇文章整理一下&#xff…

Linux格式化异常,Linux下DateFormat的parse方法出现”ParseException”异常

在windows下使用DateFormat的parse方法&#xff0c;将字符中转化为Date类型时&#xff0c;一切正常。可安装到Linux下&#xff0c;就出现了ParseException异常。代码如下&#xff1a;public Date toDateTime(String str){Date dt new Date();try{DateFormat df;df DateFormat…

如何发现优秀的开源项目?

之前发过一系列有关 GitHub 的文章&#xff0c;有同学问了&#xff0c;GitHub 我大概了解了&#xff0c;Git 也差不多会使用了&#xff0c;但是 还是搞不清 GitHub 如何帮助我的工作&#xff0c;怎么提升我的工作效率&#xff1f; 问到点子上了&#xff0c;GitHub 其中一个最重…

自已开发完美的触摸屏网页版仿app弹窗型滚动列表选择器/日期选择器

手机端网页版app在使用下拉列表时&#xff0c;传统的下拉列表使用起来体验非常不好&#xff0c;一般做的稍好一点的交互功能界面都不会直接使用下拉列表&#xff0c;所以app的原生下拉列表都是弹窗列表选择&#xff0c;网页型app从使用体验上来当然也应该做成那样&#xff0c;前…

*args, **kwargs的用法

python 中参数*args, **kwargs def foo(*args, **kwargs): print args , args print kwargs , kwargs print ---------------------------------------if __name__ __main__: foo(1,2,3,4) foo(a1,b2,c3) foo(1,2,3,4, a1,b2,c3) foo(a, 1, None, a1, b2, c3)输出结果如下&…

一个 js 中值传递和引用传递的坑。

今天在调试代码时遇到一个问题&#xff0c;刚开始想不明白&#xff0c;然后分析了一下后&#xff0c;才知道其中的问题&#xff0c;这也是一个基础的问题&#xff0c;&#xff08;所以基础是很重要的&#xff09; 代码如下&#xff1a; var a 3; a a * 2; console.log(a); //…

linux运维适合女生么,女生真的不适合做IT行业吗?Linux运维适合女生学习吗?

在很多人的脑海中都是女生不适合做IT&#xff0c;IT行业不适合女性。可能传统的思想中&#xff0c;女生只适合做文职工作&#xff0c;比如说幼师、公务员、会计等&#xff0c;就因为这样的思想也让IT行业男女出现了失衡的情况&#xff0c;那么作为女生真的不适合做IT行业吗?Li…

关于在用异步消息处理机制使用Message.Obtain()方法(而非New Message)获得一个Message对象的好处

类概述 定义一个包含任意类型的描述数据对象&#xff0c;此对象可以发送给Handler。对象包含两个额外的int字段和一个额外的对象字段&#xff0c;这样可以使得在很多情况下不用做分配工作。 尽管Message的构造器是公开的&#xff0c;但是获取Message对象的最好方法是调用Messag…

python编程中的if __name__ == 'main': 的作用和原理

大多数编排得好一点的脚本或者程序里面都有这段if __name__ main: &#xff0c;虽然一直知道他的作用&#xff0c;但是一直比较模糊&#xff0c;收集资料详细理解之后与打架分享。 1、这段代码的功能 一个python的文件有两种使用的方法&#xff0c;第一是直接作为脚本执行&…

vim 配置

vim包下载 https://github.com/spf13/spf13-vim 安装教程 http://blog.csdn.net/u011729865/article/details/49210841 https://www.zhihu.com/question/20151659转载于:https://www.cnblogs.com/aituming/p/6013279.html

自己简单封装的自己项目需要的http请求

2019独角兽企业重金招聘Python工程师标准>>> package www.tydic.com.util;import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Http…

excel导入linux乱码怎么解决方法,,请大家都来看下,Excel导入有乱码?原因出在哪里?应该怎么解决?...

老师&#xff0c;感谢你再次的回答。我按照您的方法操作&#xff0c;转换utf-8另外为CSV格式&#xff0c;然后这个CSV格式在Notepad 编辑器中打开后&#xff0c;没有乱码&#xff0c;μ 符号(希腊字符)正确显示。我想导入文件已经准备完毕&#xff0c;当我导入的时候&#xff0…

Oracle 正则表达式

一. 正则表达式简介: 正则表达式&#xff0c;就是以某种模式来匹配一类字符串。一旦概括了某类字符串&#xff0c;那么正则表达式即可用于针对字符串的各种相关操作。例如&#xff0c;判断匹配性&#xff0c;进行字符串的重新组合等。正则表达式提供了字符串处理的快捷方式。…

python编程中的if __name__ == 'main': 的作用和原理[2]

这个问题来自于知乎用户的提问&#xff0c;当时看到这个问题&#xff0c;我只是做了下简单的回答。后来我发现&#xff0c;对于很多人来说&#xff0c;更准确的说应该是大部分的 Python 初学者&#xff0c;对这个问题理解的不是很深刻。所以这里我来做下总结&#xff0c;并试图…

Java基础中按值传递和引用传递详解

下面是我在网上看到的一个帖子&#xff0c;解释的感觉挺全面&#xff0c;就转过来&#xff0c;以供以后学习参考&#xff1a; 1&#xff1a;按值传递是什么 指的是在方法调用时&#xff0c;传递的参数是按值的拷贝传递。示例如下&#xff1a; [java] view plaincopy public cla…

【Foreign】采蘑菇 [点分治]

采蘑菇 Time Limit: 20 Sec Memory Limit: 256 MBDescription Input Output Sample Input 51 2 3 2 31 21 32 42 5Sample Output 10912911HINT Main idea 询问从以每个点为起始点时&#xff0c;各条路径上的颜色种类的和。 Solution 我们看到题目&#xff0c;立马想到了O(n^2)…

c语言迷宫游戏怎么存放坐标,求解迷宫问题(c语言,很详细哦

《求解迷宫问题(c语言,很详细哦》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《求解迷宫问题(c语言,很详细哦(5页珍藏版)》请在人人文库网上搜索。1、求迷宫问题就是求出从入口到出口的路径。在求解时 , 通常用的是 “穷举求解”的方法 ,即从入口出发 ,顺某一方向向…

模块概述

概述 目前代码比较少&#xff0c;写在一个文件中还体现不出什么缺点&#xff0c;但是随着代码量越来越多&#xff0c; 代码就越来越难以维护 为了解决难以维护的问题&#xff0c;我们把很多相似功能的函数分组&#xff0c;分别放到不同的文件中取。这样每个文件所包含的内容相…