前面一篇文章 《android studio的入门使用》

已经讲了如何导入一个开源的项目。本文则来讲如何使用这些开源的资源,以及在一个小app的开发中遇到的问题。因为不可能面面俱到,所以争取用最简明,通俗的方式来叙述。

目录.jpg

层级的划分

我们写一个稍微复杂的App的时候,不可能只有一个包,必定分门别类。而分类的标准,大部分应该是遵循这三类view(UI层),bussiness(逻辑处理层),还有data(数据层)。然后我们根据这个标准把他们放在不同的包里面。这样一来,结构,逻辑都很清晰。例如这个项目里面:

分层.jpg

包名

用途

Base

包含一些基类

domain

存放一些javabean的类

Fragment

顾名思义存放fragment的类

Global

存放网络的全局类

Utils

工具类

View

改写后的布局类

它们分工明确,内容一目了然。每个人的习惯都不尽相同,找到自己熟悉的命名方式,结构明了就好。

命名方式

关于命名的规范

1.对于类名我们使用:UpperCamelCase风格编写

UpperCamelCase.jpg

2.对于方法名我们使用:LowerCamelCase风格编写

LowerCamelCase.jpg

这两个都是驼峰命名,一个是大驼峰(每个单词的首字母大写),一个是小驼峰(除第一个单词以外的单词首字母大写)。这种方式命名美观,简洁。我纵观了一下整个项目代码,发现有些时候不是按照上面的规则,而是例如fragment_left_menu这样的下划线命名,所以其实并没有唯一的标准,只是可以的话尽量这样命名我们的代码。

基类的创建

顾名思义,基类,即为初始类。如果两个以上的类同时拥有相似的特征,我们就把它抽取出来单独形成一个类。就好比我们在一个类的两个不同的函数中,需要使用同一个参数,这时我们也会习惯性的把它变成全局的变量供两个函数使用。

基类编写.jpg

假如我们现在要写5个页面,显然界面各不相同,但是我们要为它们编写一个共同的基类。我们发现无论页面怎么变,它的标题栏是大同小异的。

页面.jpg

标题栏大家很熟悉,ImageButton和TextView,下面我们不知道是什么,就用一个帧布局Framelayout代替。以后如果要添加一个不同的布局,它有一个方法addview()便搞定了

上面的代码,只是一个模板,给大家提供思路,我们需要初始化界面,初始化数据,mMainActivity的作用除了在Inflate函数里充当上下文的参数(应该改为public类型),其实在对象的流动传递里也有很大的作用,后面再叙述。除此之外如果你有必要,还可以来个类的初始化public BaseTab(){},又或是把view抽取出来当作公共参数,又或者你必须规定子类实现某个方法,某个函数,那就把整个基类写成抽象类。

开源项目的使用

最火项目.jpg

sliding menu.jpg

我们随便百度,都可以搜索到一些很热门的,很好用的开源项目。当然还是像上一篇说的,你可以直接在github下载下来,然后关联到你的项目,具体做法上一篇已经讲了,现在我就假设你已经导入好了。

Sliding Menu

因为使用过程中,有牵扯到Fragment,所以就一起讲了。

sliding menu顾名思义侧边栏,最直观的如图片所示(网络图):

侧边栏.gif

public class MainActivity extends SlidingFragmentActivity {

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_NO_TITLE);

/* 都声明为framelayout */

setContentView(R.layout.mainactiviy);

//设置側邊栏

setBehindContentView(R.layout.left_menu);

//获取侧边栏对象

SlidingMenu slidingMenu=getSlidingMenu();

//设置全屏拖动

slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);

//设置屏幕的预留宽度

slidingMenu.setBehindOffset(400);

initFragment();

}

现在结合代码说下最简单的用法,我们首先继承SlidingFragmentActivity,然后我们为主页面和侧边栏都设置一个xml的布局,这两个布局都只有一个 framelayout 方便我们之后换成其他的布局,我们的主页面和侧边栏的页面都用fragment实现,等下再说。

接着我们要获取侧边栏对象,它有个方法getSlidingMenu(),用as的朋友,直接再quick fix一下(Alt+Enter),对象就出来了。我们为它设置参数:

方法

用途

setBehindContentView

设置侧边栏的布局文件

方法

用途

setTouchModeAbove

设置拖动的位置 有全屏 不设置 左边 右边等

设置滑动.jpg

方法

用途

setBehindOffset

设置屏幕的预留宽度 其实也就是变向设置你拖出来的大小

方法

用途

toggle

隐藏侧边栏

接下来我们要创建两个Fragment去填补上面的framelayout。

Fragment

记得以前学习Fragment的时候,一头雾水,分为什么静态和动态。但随着时间推移,慢慢的就清晰很多了。所以当你遇到一时理解不了的问题,放一放,过一阵子再回头看,会明白许多。

我们现在只讲如何动态创建Fragment:

大致流程应该是这样

1.我们的Activity 的布局文件只有一个帧布局

2.创建管理者

3.开启事物

4.替换

5.提交事务

具体代码如下:

private void initFragment(){

//管理者

FragmentManager fm = getSupportFragmentManager();

//开启事物

FragmentTransaction transaction = fm.beginTransaction();

//替换

transaction.replace(R.id.fl_left_menu,new Fragment_left_menu(),FRAGMENT_LEFT_MENU);

transaction.replace(R.id.fl_content, new Fragment_content(), FRAGMENT_CONTENT);

//提交

transaction.commit();}

我们在替换这个函数里面,3个参数分别代表:replace(对应framelayout的id,要替换的类,Tag标签)

如果你只是一个fragment类,写完替换进去就搞定了,现在我们这个是两个Fragment,我们可以学以致用,写一个BaseFragment基类继承fragment。

到此我们已经动态创建完了,那设置Tag有什么用呢。我们设置标签,当然是为了获取它的对象。假如我们想获取侧边栏的Fragment对象,我们可以这样做:

private static final String FRAGMENT_LEFT_MENU ="fragment_left_menu" ;

我们在开头声明一个静态的变量

这样我们在替换的时候就设置好了他们对应的tag值

最后只要写一个函数,通过管理者就可以轻松获得Fragment对象了:

public Fragment_left_menu getleftMenuFragment(){

//管理者

FragmentManager fm = getSupportFragmentManager();

Fragment_left_menu fragment = (Fragment_left_menu) fm.findFragmentByTag(FRAGMENT_LEFT_MENU);

return fragment;

}

官方是非常推荐我们使用fragment的,所以大家赶紧学起来吧。就好像以前大家都不习惯写Viewholder,现在也被强迫着写了。最后附赠一个思维导图帮助大家理解它:

Fragment的使用.png

xutils

工具包:提供一些方便的工具为我们使用,有四大模块:DbUtils,ViewUtils,HttpUtils,BitmapUtils

1.注释

为了解决频繁的findviewbyid,于是就有了这个ViewUtils(其实好像也没快多少)

用法(来自官方文档):

//在Activity中注入:

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

ViewUtils.inject(this);

//注入view和事件 ...

textView.setText("some text...");

...

}

//在Fragment中注入:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

View view = inflater.inflate(R.layout.bitmap_fragment, container, false);

// 加载fragment布局

ViewUtils.inject(this, view);

//注入view和事件 ...

}

最后只需在你需要UI绑定或者事件绑定的语句前加个注释即可如:

@ViewInject(R.id.textView)

TextView textView;

@OnClick(R.id.test_button)

public void testButtonClick(View v) {

...}

2.网络工具

我们可以通过HttpUtils请求网络,方便的获取网络数据。

以解析json为例,你可以这样做:

private void getDatafromServer() {

HttpUtils httpUtils=new HttpUtils();

httpUtils.send(HttpRequest.HttpMethod.GET, murl, new RequestCallBack()

{

public void onSuccess(ResponseInfo responseInfo) {

String result = responseInfo.result;

System.out.println("页签结果是" + result);

parsedata(result);

}

public void onFailure(HttpException error, String msg) {

Toast.makeText(mActivity, msg,Toast.LENGTH_SHORT).show();

error.printStackTrace();

}

});

}

我们首先创建一个HttpUtils对象,在send方法里面,有三个参数分别是(请求的方法(get,post),地址,放回的类型),在匿名内部类中有两个函数:一个是成功,获得数据后,我们可以让它进一步对数据解析。一个是失败,我们可以让他在logcat里打印错误日志并toast出问题在哪。

这个时候我们假设已成功获取了json数据,接着对它进行解析:

protected void parsedata(String result) {

Gson gson=new Gson();

tabDetaildata = gson.fromJson(result,Tabdata.class);

....

}

我们借助gson的fromjson方法传入刚获得的结果和一个javabean类,就可以成功解析json数据了。

注意:getDatafromServer()这个方法是运行在主线程的,所以在里面的方法当然可以随意对UI进行设置

3.解析网络图片

我们以前常使用线程,异步加载的方式下载网络图片,还要担心内存溢出等问题,现在只需使用BitmapUtils几行代码就可以决解这样复杂的问题。

以listview里加载网络图片为例:

/* 新闻列表的适配器 */

class NewslistAdapter extends BaseAdapter{

private BitmapUtils utils;

public NewslistAdapter(){

utils=new BitmapUtils(mActivity);

utils.configDefaultLoadingImage(R.mipmap.pic_item_list_default);

}

···

}

我们在内部初始化的时候传入当前上下文(mActivity)声明一个全局的BitmapUtils对象,其中configDefaultLoadingImage方法是用来预加载图片。

utils.display(hodler.listIcon,tabnewsData.listimage);

最后在适配器的getview函数中,对UI进行设置。它有个display()函数分别填入view和要添加的图片数据,这样就大功告成了。

ViewpagerIndicator

1.我们首先介绍的是viewpage的导航指示器:TabPageIndicator,比较直观的如图所示(网络图):

滑动.gif

viewpagerindicator.jpg

如图,我们先把TabPageIndicator的路径拷贝下来,在所在viewpage的xml上添加对应的布局:

android:id="@+id/indicator"

android:layout_width="match_parent"

android:layout_height="wrap_content" />

最后,只需在初始view的时候,绑定一下UI

myIndicator= (TabPageIndicator)view.findViewById(R.id.indicator);

并且在viewpager添加完适配器之后,指示器再绑定viewpager

//添加适配器

mviewPager.setAdapter(new MenudetailAdapter());

viewpagermyIndicator.setViewPager(mviewPager);

还有一点需要注意的是,如果指示器和viewpager绑定以后,如果viewpager要设置监听事件,这时我们应该对指示器设置而不是viewpager自身。

2.CirclePageIndicator

有时我们翻阅图片,为了有个指示的效果:

CircleIndicator.gif

这时我们就用到CirclePageIndicator

和上面的一样,我们首先在布局文件中将其添加

circlepageindicator.jpg

我们看到里面有自定义控件的属性app,所以首先当然把命名空间给引入,在头文件的地方添加

xmlns:app="http://schemas.android.com/apk/res-auto"

接着初始化,然后绑定viewpager,和上面一样。它有两个方法值得提一下, setSnap()填入(true,false)表示点是否跳跃,也就是我们上方展示图片的效果。onPageSelected()选择初始停留的页面。

事件的拦截机制

为了便于理解,我画了一个思维导图

事件传递机制.jpg

由Activity把事件分发出去->到了最外层子控件->最外层子控件通过dispatchTouchevent接收分发的事件->传给onInterceptTouchevent,由它决定是否拦截,若拦截就交给onTouchevent对事件进行处理,若不拦截就继续传到内层的子控件->若所有子控件都不处理,则返回给activity处理。

我们现在回到实际的项目中,来讨论事件在具体的例子中如何实现拦截:

手绘UI.jpg

这个app的界面中,最左边有个侧边栏(Sliding menu),最外面是一个由tab来切换的viewpager1,第二层是由viewpagerIndicator来切换的viewpager2,最里面的那层是一个图片切换的Viewpager3。这应该是一个比较复杂的事件拦截的案例了,我们再来画一个清晰的图:

事件拦截.jpg

我们常用到事件拦截,是在重写一个属于我们自己的自定义view的时候。例如在写最外层的Viewpager1的时候,我们希望它没有滚动这个功能,而是通过tab来控制页面的翻阅,而且我们希望它不拦截事件,而是让内层的viewpager可以接受到事件,就可以在重写的viewpager里这样做:

//停止滚动

public boolean onTouchEvent(MotionEvent ev) { return false;}

//事件是否拦截

public boolean onInterceptTouchEvent(MotionEvent ev) { return false;}

在写viewpager2的时候,遇到了问题,我们发现如果我们往右划的时候,slidingmenu这个父控件会拦截我们的右划事件。所以这个时候我们必须重写一个viewpager类,来规定事件的拦截。

//请求父类不拦截触摸事件

public boolean dispatchTouchEvent(MotionEvent ev) {

if(getCurrentItem()!=0) {

getParent().requestDisallowInterceptTouchEvent(true);

}else {

getParent().requestDisallowInterceptTouchEvent(false);

}

return super.dispatchTouchEvent(ev);

}

我们在事件分发的这个方法中,调用requestDisallowInterceptTouchEvent这个方法,来请求父类不拦截触摸事件,所以当当前的页面不是第一页的时候,我们就不拦截,否则我们拦截。

之后我们写到viewpager3, 我们希望可以自由的划动里面的图片, 所以不希望父类拦截我们的事件,在重写的viewpager里:

public boolean dispatchTouchEvent(MotionEvent ev) {

getParent().requestDisallowInterceptTouchEvent(true);

return super.dispatchTouchEvent(ev);

}

可是问题就来了,你这里不希望被拦截,但是它的父类viewpager2在第一个页签往右划的时候会规定会被sliding menu拦截,所以我们发现viewpager3在第一个页签往右划的时候还是会引出sliding menu,而不是往前面翻图片。出现了矛盾,这里我们就需要对代码进行重构:我们不给viewpage2重写类,而是给它设置监听(setOnPageChangeListener)

public void onPageSelected(int position) {

//判断页面 控制slidingmenu是否划出

MainActivity mainActivity= (MainActivity) mActivity;

SlidingMenu slidingMenu = mainActivity.getSlidingMenu();

if(position==0){

slidingMenu.setTouchModeAbove(slidingMenu.TOUCHMODE_FULLSCREEN);

}else{

slidingMenu.setTouchModeAbove(slidingMenu.TOUCHMODE_NONE);

}

}

viewpager3的重写类,我们也做出新的事件拦截规定,我们规定

1.第一个图片往右滑动 跳到上一个页签(或侧边栏)

2.最后一个图片往左滑动 跳到下一个页签

3.向下划的时候

需要拦截,于是:

public boolean dispatchTouchEvent(MotionEvent ev) {

switch(ev.getAction()){

case MotionEvent.ACTION_DOWN:

//先让父类不拦截子类的事件

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(getCurrentItem()==getAdapter().getCount()-1){

getParent().requestDisallowInterceptTouchEvent(false); }

}

}else{

//下划 拦截

getParent().requestDisallowInterceptTouchEvent(false);

}

break;

default:

break;

}

return super.dispatchTouchEvent(ev);

}

到此我们就管理好了这个复杂的事件拦截家族

传递

我们在开头的时候,说到mActivity是充当当前上下文的作用,除此之外我们还可以拿它来传递对象。比如我们要在后面的页签类里,写个函数控制sliding menu的拖出与隐藏,我们前面说过这个函数是toggle。但是我们必须获得一个是sliding menu的对象,但是要获得sliding menu对象,我们首先得获得MainAcitvity的对象。于是这里就要我们灵活的进行对象的传递:

private void toggleSlidingMenu() {

//获得slidingmenu对象

MainActivity mainActivity= (MainActivity) mActiviy;

SlidingMenu slidingMenu = mainActivity.getSlidingMenu();

slidingMenu.toggle();

//切换状态

}

对于数据的传递,每个项目都有可能错综复杂,在android studio里有个很方便的快捷键,帮助我们找到哪些地方用到了这些数据。

选中要查找的目标,按住alt+F7(find usages):

引用.jpg

这个时候我们还可以右键:

跳转.jpg

跳转到引用的页面,迅速帮助我们定位,这样我们就不会晕头转向了。

以上就是我重点要讲的,如有不足请多多包涵,也希望大家可以支持我,谢谢!

android 热门开源库,GitHub安卓热门开源资源在项目中的使用及项目总结相关推荐

  1. 怎么从开源库github.com 下载

    github.com是一个开源库,大量的开源代码等着你去学习,但怎么下载呢?我一直有些迷惑,所以总结一点点放这里. 在开源工程主目录下,在Clone or download 按钮处点击,然后选择 Do ...

  2. 最新Android开源库、工具、开源项目整理分享

    热文导读 | 点击标题阅读 金九银十跳槽季如何进阶找到合适满意的工作? Android 进阶/面试 重难点 要来了!国内安卓统一推送标准将于今年3月开启测试 作者:lovesosoi 来源:https ...

  3. 【转】DCMTK开源库的学习笔记3:dcmtk文件中数据元的修改

    转自:https://blog.csdn.net/zssureqh/article/details/8804736 dcm文件是医学领域DICOM3.0标准所对应的主要的文件格式.前两篇学习笔记中,学 ...

  4. android自定义视频列表,Github最火开源项目-高仿今日头条视频列表功能

    主要特点视频全屏播放和浮层小窗播放 可以完全自定义UI 能在ListView.ViewPager和ListView.ViewPager和Fragment等多重嵌套模式下全屏工作 手势修改进度和音量 视 ...

  5. python的开源库是什么_python开源库列表

    标准库 Python标准库描述了 Python 语言的具体语法和语义,这份库参考则介绍了与 Python 一同发行的标准库.它还描述了通常包含在 Python 发行版中的一些可选组件. API手册:h ...

  6. android jar 反射,android 第三方jar库 反射得到自己的资源ID

    做jar,jar代码获取资源不能直接引用 R.xx.name, 有两种方法: 1.通过方法: int android.content.res.Resources.getIdentifier(Strin ...

  7. Android常用开源库整理汇总

    1.基本控件 1.1.TextView ScrollNumber ReadMoreTextView HtmlImage android-autofittextview html-textview Ba ...

  8. Android开源库大全分类汇总(Android技术资料汇总)

    1.基本控件 1.1.TextView ScrollNumber ReadMoreTextView HtmlImage android-autofittextview html-textview Ba ...

  9. Android开源库大全分类汇总(Android技术资料汇总)...

    1.基本控件 1.1.TextView ScrollNumber ReadMoreTextView HtmlImage android-autofittextview html-textview Ba ...

最新文章

  1. xmemcached发布1.3.4
  2. mysql crm动态列设计_值得收藏:一份非常完整、详细的MySQL规范
  3. ASP.NET操作文件大全
  4. raid5 合适 多少块硬盘_raid1 raid2 raid5 raid6 raid10如何选择使用?各需要几块硬盘?...
  5. 虚拟化关键技术及解决方案
  6. linux之移动或重命名文件:mv
  7. linux tty core code,linux tty core 源码分析(8)
  8. 短线交易有这些特点的,慎做短线交易
  9. INK1003注意事项
  10. 软件测试的目的和意义是什么?
  11. 在豌豆荚安卓市场下载了伪造的ES文件管理器,该流氓apk会自动的下载手机游戏
  12. 被一些数字整除的数字的特征
  13. 大数相减(解析国密sm2_bn_sub算法与自定义算法)
  14. Word插入题注快捷键
  15. 红轴和青轴哪个手感好 红轴和青轴哪个玩游戏好
  16. 通过ssh-keygen命令生成SSH密钥
  17. 如何解除WORD限制编辑
  18. Java波斯王子时之沙攻略_波斯王子时之沙详细操作按键指南
  19. js 获取input 中name值的问题
  20. RedHat Enterprise Linux Server 6.4 迅雷快传 下载地址

热门文章

  1. “鉴定一下网络热门平台上的小广告”
  2. 微博发布公告 将开展财经违规内容专项整治行动
  3. 有点贵但卖光了!这款旗舰要火了吗...
  4. 拿完年终奖换工作?频繁跳槽职场人工资低于同龄人平均水平
  5. iPhone 12搭载5nm A14芯片:晶体管数量高达150亿
  6. 受疫情影响 MWC 2020正式取消
  7. 微软拿下美国国防部100亿美元云合同,亚马逊不干了...
  8. 快了!华为Mate X国内发布时间曝光:另有麒麟990版本
  9. 拼多多上买车,累计上线70个小时,成交订单9463笔!
  10. 电竞人才平均月薪感受下!上海薪资领跑全国