二级列表(ExpandableListView)
①创建布局,找控件
②获取数据:死数据、网络数据
③创建适配器:10个方法要掌握
④设置适配器
⑤父项、子项点击事件
⑥基本属性
Listview手动、自动加载更多
(1)Listview
①创建布局,找控件
②获取网络数据
③创建适配器:两个优化(必会):convertView复用,避免重复找控件
④设置适配器
(2)Listview手动加载更多
①创建布局,找控件
②获取网络数据
③创建适配器:两个优化(必会)
④设置适配器
⑤给Listview添加一个footer
⑥点击footer中button加载更多:page++,获取数据
(3)Listview自动加载更多
①创建布局,找控件
②获取网络数据
③创建适配器:两个优化(必会)
④设置适配器
⑤定义一个变量isBottom表示是否滑到底部
⑥Listview设置滑动监听
侧滑菜单
①添加依赖
②创建布局:DrawerLayout、NavigationView(三个属性、menu)
③设置actionbar:toolbar设置标题、logo、关联toobar和侧滑菜单
④监听事件:头部监听、侧滑菜单监听、DrawerLayout、代买开关侧滑菜单
⑤沉浸式状态栏
选项菜单
①创建选项菜单(onCreateOptionsMenu):两种方式-代码和menu(showAsAction)
②选项菜单的点击事件(onOptionsItemSelected):switch
上下文菜单
①注册上下文菜单:registerForContextMenu()
②创建上下文菜单:onCreateContextMenu()
③上下文菜单点击事件:onContextItemSelected()
作业:
练习册的思路:
1.导入依赖 获取权限
* 2.创建布局,找控件id
* 3.设置toolbar和侧滑的属性
* 4.设置侧滑的监听 吐丝每个的内容
* 5.设置listview 获取数据并解析
* 6.给listview设置上下文菜单
* 7.每个按钮给与相应的功能
第十题思路:
1.创建dl布局 上方第一个Toolbar,然后ViewPager,还有侧滑菜单的功能
* 2.使侧滑与toolbar结合
* 3.创建适配器使Fragment与ViewPager和TabLayout相结合
* 获取二级列表的数据
* 4.创建可以拖动的那个tablayout 将解析的数据添加到其中
* 5.创建循环使每个标题获取数据
* 6.创建公共的Fragment
* 7.创建适配器和封装类 得到图片和内容
* 8.将获取的图片和内容的数据添加到列表
* 9.不要忘了开始添加依赖和请求网络数据
RecyclerView基本使用
①添加依赖(版本问题注意)
②创建布局(宽高必须是充满的)
③找控件
④设置布局管理器(三种显示方式:线性布局、网格布局、瀑布流布局)
⑤获取数据(切换子线程的方法)
⑥创建适配器-- 重写三个,通过接口回调实现点击事件
⑦设置适配器
RecyclerView多布局一:list+banner
① RecyclerView基本使用
②定义类型常量
③重写方法getItemViewType()根据位置返回不同类型
④重写oncreateViewHolder()根据不同类型加载不同的布局
⑤重写onBindViewHolder()根据不用类型加载不同数据
注意
①获取条目总数:list.size()+1
②onBindViewHolder:获取别表条目数据的时候,position-1
RecyclerView多布局二:奇数位置左图右文字+偶数位置左文字右图片
① RecyclerView基本使用(看6)
②定义类型常量
③重写方法getItemViewType()根据位置返回不同类型
④重写oncreateViewHolder()根据不同类型加载不同的布局
⑤重写onBindViewHolder()根据不用类型加载不同数据
注意:没有7中注意
RecyclerView通过接口回调实现点击事件
①在adapter定义一个内部接口,内部接口定义一个方法,方法参数是我们需要返回值的;
②在adapter定义接口变量,并设置set方法
③在onBindVIewholder()中,给条目做一个点击事件
④在fragment或者activity中,使用adapter对象调用点击事件即可
RecyclerView添加刷新
①添加依赖
②在布局中添加刷新的控件并找控件
③给刷新控件添加加载更多、下拉刷细腻添加监听,监听中写具体代码
④刷新完毕列表,关闭SmartRefreshLayout头和脚。
四、fragment
静态添加fragment
①创建一个fragment
②创建布局,把①中的fragment放到布局中
注意:
①必须要有id,否则:Caused by: java.lang.IllegalArgumentException: Binary XML file line #9: Must specify unique android:id, android:tag, or have a parent with an id for com.anfly.fragmentr.AFragment
②布局中必须添加属性name,值该fragment全类名
动态添加fragment
//获取碎片管理器
FragmentManager fm = getSupportFragmentManager();
//开启事务
FragmentTransaction fragmentTransaction = fm.beginTransaction();
//获取fragment对象
AFragment aFragment = new AFragment();
//替换容器中内容
fragmentTransaction.replace(R.id.fl_container, aFragment);
//提交事务
fragmentTransaction.commit();
Transaction常用方法
①add
②remove
③replace
④hide
⑤show
⑥attach
⑦detach
⑧commit
fragment生命周期
①onAttach()
②onCreate()
③onCreateView()
④onActivityCreated()
⑤onStart()
⑥onResume()
⑦onPause()
⑧onStop()
⑨onDestroyView()
⑩onDestroy()
⑪onDetach()
fragment传递数据到activity
①获取activity对象,直接调用方法
MainActivity activity = (MainActivity) getActivity();
activity.getMsgFromFramgent("我是来自fragment的数据");
②接口回调传递数据
Java接口与接口回调在Android中的使用
③通过fragment的有参构造传数据(不推荐)
activity传递数据到fragment
①通过bundle方式传值
activity中:
AFragment aFragment = new AFragment();
Bundle bundle = new Bundle();
bundle.putString("a", "我是来自activity的数据");
aFragment.setArguments(bundle);
fragment中:
Bundle bundle = getArguments();
String a = bundle.getString("a");
fragment与fragment之间传递数据
①通过构造方式传值(不推荐)
②通过FragmentManager找到对应Id或者Tag的Framgment,然后获取里面的数据或方法
③通过它们所在的Activity作为桥梁,可以使用getActivity()或者接口回调,达到获取另一个Fragment数据的目的.
五、ViewPager+tablayout
ViewPager结合view实现导航
①创建布局找控件
②获取数据集合
③创建适配器:
getCount()isViewFromObject() instantiateItem()destroyItem()
④设置适配器
Viewpager结合Fragment实现导航
①创建布局找控件
②获取fragment的集合fragments
③创建适配器:FragmentStatePagerAdapter和FragmentPagerAdapter区别以及内部方法
④设置适配器
Banner开源框架
banner.setBannerStyle(BannerConfig.NUM_INDICATOR_TITLE)//设置风格.setImages(images)//设置图片集合.setBannerAnimation(Transformer.DepthPage)//设置动画.setBannerTitles(titles)//直接添加无效,必须设置BannerStyle.setImageLoader(newGlideImageLoader())//图片加载器.start();
Tablayout
①属性
TVF
①创建布局找控件:TV
②创建两个集合:fragments和titles
③创建适配器:四个方法(包含一个构造)
④设置适配器
⑤TV结合:tab.setupWithViewPager(vp);
⑥设置图片选择器tab.getTabAt(0).setIcon()
TVF涉及到的懒加载
Version:1.0StartHTML:000000201EndHTML:000022817StartFragment:000008969EndFragment:000022779StartSelection:000008969EndSelection:000022779SourceURL:https://www.jianshu.com/p/fe890d03854c
六、PopupWindow
①创建PopupWindow布局
②创建PopupWindow对象,用三个参数的构造
③PopupWindow四种显示方式
④聚焦:EditText能输入内容
⑤点击范围外关闭PopupWindow
⑥全屏阴影,PopupWindow点击消失监听
⑦进出场动画
七、Notification
①获取通知管理器getSystemService
②兼容O版以上系统
③获取通知对象(构建者模式):必要属性有三项
④用通知管理器发送通知
⑤延时意图:intent、pendingIntent、setContentIntent
⑥通知提示:声音、震动、呼吸灯、全部
八、权限
分类
①普通权限:不需要动态获取
②危险权限:需要动态获取
危险权限分类
3CSLMP
如何动态获取权限
①在清单列表写上需要的全下你
②检查是否授权
如果授权 -> 操作
如果没有授权 -> 请求权限
if(ActivityCompat.checkSelfPermission(this,Manifest.permission.CALL_PHONE)==PackageManager.PERMISSION_GRANTED){callPhone();}else{ActivityCompat.requestPermissions(this,newString[]{Manifest.permission.CALL_PHONE},100);}
③请求权限结果
@OverridepublicvoidonRequestPermissionsResult(int requestCode,@NonNullString[]permissions,@NonNullint[]grantResults){super.onRequestPermissionsResult(requestCode,permissions,grantResults);switch(requestCode){case100:if(grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){callPhone();}else{Toast.makeText(MainActivity.this,"授权失败",Toast.LENGTH_SHORT).show();}break;}}
通过框架获取危险权限
①添加依赖implementation 'com.github.dfqin:grantor:2.5'
②使用
PermissionsUtil.requestPermission(this,newPermissionListener(){@OverridepublicvoidpermissionGranted(@NonNullString[]permission){callPhone();}@OverridepublicvoidpermissionDenied(@NonNullString[]permission){Toast.makeText(MainActivity.this,"授权失败",Toast.LENGTH_SHORT).show();}},Manifest.permission.CALL_PHONE);
九、内容提供者
ContentProvider
①创建一个数据库及一张表
②自定义ContentProvider继承自ContentProvider,重写方法
ContentResolver
①获取ContentResolver
②获取uri:Uri.parse("content://"+authorities+/+path)
Uri uri=Uri.parse("content://com.anfly.contentproviderr.ClContentProvider/cl");
Version:1.0StartHTML:000000201EndHTML:000024388StartFragment:000009095EndFragment:000024350StartSelection:000009095EndSelection:000024350SourceURL:https://www.jianshu.com/p/fe890d03854c
3.ContentResolver读取短信、通讯录、图片、音频、视频
①动态获取危险全新
②获取ContentResolver对象contentResolver
③contentResolver调用query()方法查询相关内容
短信:Telephony.Sms.CONTENT_URI
通讯录:ContactsContract.CommonDataKinds.Phone.CONTENT_URI
图片:MediaStore.Images.Media.EXTERNAL_CONTENT_URI
音频:MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
视频:MediaStore.Video.Media.EXTERNAL_CONTENT_URI
十、Service
service概述、应用场景
startService生命周期
bindService生命周期
startService和bindService区别
Activity和Service之间的数据传递
①数据从Activity和到Service
intent方式:startService和bindService都可以
②数据从Activity到Service
IBinder方式:bindService
③数据从Service到Activity
接口回调和广播
十一、音乐播放器
MediaPlayer创建方式
①MediaPlayer mp = new MediaPlayer();
②MediaPlayer mp = MediaPlayer.create(this, R.raw.test);
四种资源
①用户在应用中事先自带的resource资源
例如:MediaPlayer.create(this, R.raw.test);
②存储在SD卡或其他文件路径下的媒体文件
例如:mp.setDataSource("/sdcard/test.mp3");
③网络上的媒体文件
例如:mp.setDataSource("http://music.163.com/song/media/outer/url?id=139894.mp3");
④assets目录下文件
AssetManager assets=getAssets();try{AssetFileDescriptor assetFileDescriptor=assets.openFd("qinghuaci.mp3");player.setDataSource(assetFileDescriptor.getFileDescriptor(),assetFileDescriptor.getStartOffset(),assetFileDescriptor.getLength());player.prepare();player.start();}catch(IOException e){e.printStackTrace();}
assets 和 raw 资源文件夹区别
结合SeekBar实现拖动播放音乐功能
①创建seekbar布局
②seekbar设置监听,在停止拖动中player.seekTo(seekBar.getProgress());
③更新seekbar:
privatevoidupdataProgress(){newThread(newRunnable(){@Overridepublicvoidrun(){while(player.isPlaying()){try{Thread.sleep(1000);seekbar_mp.setMax(player.getDuration());seekbar_mp.setProgress(player.getCurrentPosition());}catch(InterruptedExceptione){e.printStackTrace();}}}}).start();}
结合RecyclerView实现音乐播放上一首,下一首功能
① 使用ContentResolver+recyclerview展示音乐列表
②条目点击事件播放对应的音乐
③点击上一首、下一首
privatevoidnext(){if(positon<list.size()-1){positon++;}else{positon=0;}player(list.get(positon).getPath());}privatevoidpre(){if(positon>0){positon--;}else{positon=list.size()-1;}player(list.get(positon).getPath());}
结合Service实现后台音乐播放功
结合Service实现后台音乐播放功能
①创建一个服务AudioService
②服务中创建内部类AudioBinder,类中有一个方法返回服务类
③在onCreate()初始化MediaPlayer对象
④创建一系列关于mp的方法:播放、暂停、继续、停止、拖动
⑤在AudioActivity中绑定服务,返回服务类的对象
⑥按钮点击事件:通过服务类对象调用其方法实现音频播放
⑦seekbar进度改变监听,把进度传给mp