手机影音
02 Splash页面和MainActivity主页面进入
1.设置onTouchEvent点击会立刻进入主页面,onTouchEvent down up 和两秒后共执行了三次,启动了三次,main界面需要点击3次才能退出,所以需要在Manifest中lauchmode设置为单例模式singleTask
(1.singleInstance为在一个新的任务栈中启动一个新的activity 2.singleTask在当前任务栈中启动当前activity,如果有了就不启动了 3.singletop如果当前activity不在栈顶 创建一个新的activity 4.standard标准模式)
2.从splash进入main中立刻点击退出会有bug,会又进入main页面。
解决办法 ①是将Handler写成类的成员变量 属性的形式,创建个handler实例,最后在onDestroy中调用handler去移除所有的回调和消息。
②不用单例模式,设置默认为否,至少会进入一次主页面,进入后取反,就只会进入一次主页面了。private boolean isStartMain = false;
private void startMainActivity() {
if(!isStartMain){
isStartMain = true;
Intent intent = new Intent(this,MainActivity.class);
startActivity(intent);
//关闭当前页面
finish();
03 软件架构的分析 04主页面的布局
- mip-xxdpi要放置不同大小的图片
2. radioGroup的父类是线性布局 里面是radioButton。FrameLayout中动态的填充一个不同的Fragment,装载不同的内容(目的是中间的ListView切换 上面的线性布局不动)
上面四个页面继承BasePager,目的是做个集合泛型,动态得到四个Pager很方便。
① 实现BasePager
② 实现四个页面VideoPager AudioPager NetVideoPager NetAudioPager
③ 实例化四个页面并且放入集合汇总
④ 当点击RadioGroup时,监听RadioGroup状态变化,显示不同页面,Fragment替换不同的页面。
细节:
3.FrameLayout是五大布局中最简单的一个布局,在这个布局中,整个界面被当成一块空白备用区域,所有的子元素都不能被指定放置的位置,它们统统放于这块区域的左上角,并且后面的子元素直接覆盖在前面的子元素之上,将前面的子元素部分和全部遮挡。显示效果如下,第一个TextView被第二个TextView完全遮挡,第三个TextView遮挡了第二个TextView的部分位置。本项目这个填充整个屏幕所以权重是1。
4.对权重weight的理解
所以,要對weight做了解,要深深的理解下面兩句話:
在layout_width設置為fill_parent的時候,layout_weight所代表的是你的控件要優先盡可能的大,但這個大是有限度的,即fill_parent.
在layout_width設置為wrap_content的時候,layout_weight所代表的是你的控件要優先盡可能的小,但這個小是有限度的,即wrap_content.
layout_height 同 layout_width.
5.RadioGroup的父类是线性布局 所以可以设置方向 (orientation )
6.Android中的Selector主要是用来改变ListView和Button控件的默认背景。
在RadioButton中设置selector选择器,在selector文件中 因为是一直选用的状态,所以item设置为state checked。
7.在selector中设置文字颜色,直接android:color="#363636"。
8.android:gravity 属性是对该view中内容的限定.比如一个button 上面的text. 你可以设置该text 相对于view的靠左,靠右等位置.
android:layout_gravity是用来设置该view相对与父view 的位置.比如一个button 在linearlayout里,你想把该button放在linearlayout里靠左、靠右等位置就可以通过该属性设置.
即android:gravity用于设置View中内容相对于View组件的对齐方式,而android:layout_gravity用于设置View组件相对于Container的对齐方式
9.为了去掉radioButton中的原始圈圈效果,可以在调用其父类Button,设置transparent颜色设置为透明。"@android:color/transparent"。
10.padding 和margin的区别
在CSS中margin是指从自身边框到另一个容器边框之间的距离,就是容器外距离。在CSS中padding是指自身边框到自身内部另一个容器边框之间的距离,就是容器内距离。
11.同样的RadioButton 可以在style.xml中设置相同的内容。
12. 在导入R.id的应导入本地R包,否则报错。(在这里出个问题浪费很多时间,系统无法导入本地R包,我重新建个项目才搞定的。)
实例化 framelayout和RadioGroup,所以需要在activity.xml中设置id。初始化视图对象。需要设置默认选项使用check(R.id)方法。
创建BasePager和子页面初始化
- 首先创建个base包(我刚下载subversion),在包中创建个基类 公共类BasePager, VideoPager AudioPager NetVideoPager NetAudioPager 继承BasePager。
- ),孩子强制执行该方法,只要重写该方法就可以实现孩子不同的效果。
- 在BasePager,调用initData()方法,初始化子页面的数据。
构造方法的时候,创建视图,采用initView(在这里我查了initView 和upDateView 的区别:initView()
方法只做初始化操作,也就是仅仅只会发生一次的操作,比如findViewById()
,setListener()
之类的。而updateView()
方法中,则是去做一些根据某些成员变量,flag,boolean值之类的去变更View
的属性,会被反复调用的操作。private void updateView() { ... viewA1.setText(dataA.getContent()); viewA2.setTextColor(dataA.getTextColor()); viewB1.setImage(dataB.getImage()); viewB2.setText(dataB.getTitle()
太复杂了)
构造方法BasePager(要创建视图,所以传上下文context)。在构造方法里就调用initView(),要创建视图。将initView()创建成抽象方法(抽象方法没有方法体)。在一个类中调用抽象方法,那么这个类也要加上abstract变为抽象类。抽象类是不完整的,它只能用作基类。在面向对象方法中,抽象类主要用来进行类型隐藏和充当全局变量的角色。抽象类与具体类相比不能实例化,与接口相比还更体现细节。(抽象类是指不允许被实例化的类;抽象方法是没有方法体的方法。
1、抽象类可以不包括抽象方法,它反正不会去实例化,里面的方法是不是抽象的没有本质影响。
2、但是含有抽象方法的类绝不能被实例化,否则执行这个方法的时候,怎么办?
3、如果子类是非抽象的,那么它就必须实现父类中的抽象方法;否则,它继承来的抽象方法仍然没有方法体,也是个抽象方法,此时就与“含有抽象方法的类必须是抽象类”相矛盾了。
比如说,我在纸上画一个饼(抽象类),饼有个“吃到嘴里沾一嘴芝麻”的方法。我可以在饼上画几个点假装是芝麻,这时候“沾芝麻方法”就是个抽象方法,因为它不会真的掉芝麻;我也可以在饼上蘸点儿真芝麻,这时候“沾芝麻方法”就是个有实现的方法。但是用哪个方法都可以,因为没人会去真的吃画的饼吧。
但我要真的去照着这个图烤一个饼(非抽象子类),那这个子类的“吃到嘴里沾一嘴芝麻”的方法就必须有具体的实现。否则烤出来,一吃,没芝麻啊!食客非上消协投诉不可。
接着调用initData()方法用于子页面初始化数据,联网请求数据,或者绑定数据的时候要重写该方法。意义在于调用BasePager类就会创建视图和初始化数据,可以做到视图分离使架构更加灵活,可以动态的调配。
- 接下来创建包去实现各个子页面,还是创建类去继承BasePager。
- (此处做了专门打印日志的类LogUtil放在一个Util的包里)
目前要做的是实例化子页面,在点击radioButton的时候,动态的加载子pager页面,加到fragment中,并且替换掉FrameLayout。
在MainActivity中添加一个集合ArrayList <BasePager>(ArrayList很好用,可以添加任意类型,动态增长,各种库函数支持,如下是个简单示例, 如果程序员忘记了原来add进来的类型,然后在get的时候,转换成错误的实际类型了,就像下面这样,会怎样呢?答案是编译没有问题,运行时才会报错。这样就会有很大的风险。为了解决这个问题,一般会再封装一下ArrayList,建立自己的只允许特定类型的ArrayList,如下代码:),利用basePager调用add方法,添加视频页面。
(实现层层回调)basePager.add(new VideoPager(this));添加页面 ,当点击new VideoPager时候,就会回调VideoPager子页面类中的public VideoPager(Context context ) super.context 构造方法,此时 VideoPager子页面类被实例化,在这个过程中通过super又调用了父类(BasePager),通过父类调用了父类中的方法initView,通过initView又会调用子类页面中的initView,至此实例化了子类VideoPager。
设置RadioGroup的监听 setOnCheckedChangeListener(onclick和Oncheck的选择CheckBox的状态不一定通过点击改变,还可以通过其他的方式,比如果直接将 CheckBox对应的数据库状态值修改了,这样的话 OnClickListener就不能监听,因为状态的改变不是来自你的onClick事件,而 OnCheckChangedListener则是监听CheckBox的状态,无论来自你的onClick事件还是其他。)
具体方法:由于setOnCheckedChangeListener(参数在源码内可看见是一个接口OnCheckedChangeListener)所以在onCreat外定义类调用接口的方法。在方法参数内new 定义类(),传过去参数调用。(但是此处我的疑问是可以直接在setOnCheckedChangeListener方法内 new+接口,然后再自动调用方法,没必要新设置类啊?还有为什么要在onCreat外建类呢?因为还要在这个类中setFragement();)
接下来就是在接口调用的方法中onCheckedChanged 自己写出来实现方法,利用switch(checkId)case R.id.语句调用(细节是需要在前面加一个private int position//选中位置由此给四个子页面赋上了id 0 1 2 3 )。
动态的使用Fragment(http://www.cnblogs.com/Gaojiecai/p/4084252.html fragment深度解析)把页面添加到Fragment中,
//1.得到FragmentManger 需要得到fragmentManager(此时需要得到getSupportFragmentManager需要将 MainActivity extends Activity变为FragmentActivity)。
//2.开启事务 (善于查看源码,由此可以知道返回类型,)
//3.替换 (此时用replace(传入的R.id为xml文件中FrameLayout的id) add是在原来的基础上添加,而replace可以去掉原来的。)replace传入new Fragment(){}此时啥也没有,需要重写onCreatView方法返回视图,basePagers(basePagers为列表也就是)调用get(position)。此时还要想到如果basePager不为空的话,调用个initDate,直接返回return basePager.rootView(此时的小插曲是我无法调用rootView,查看后发现是在基类中我定义rootView属性时定义为了私有属性改为public。),返回到基类上 动态的加载各个页面。
//4.提交
(此时进入页面时虽然默认选择了videoButton,但是在页面上没有初始化。解决办法是把设置默认选中项check方法放到设置RadioGroup监听的后面。)
页面视图初始化后,页面数据初始化。