1.ExpandableListView (二级列表)
①创建布局 找控件
②获取数据 (死数据 ,网络数据)
③创建适配器 继承 BaseExpandableListAdapter() 重写十个方法
④设置适配器 两个优化:convertView复用,避免重复找控件
⑤监听 父项 setOnGroupClickListener()
子项 setOnChildClickListener()
2.ListView(手动,自动加载更多)
①设置布局 找控件
②获取数据
③创建适配器 继承 BaseAdapter()
④设置适配器 刷新
(1)手动加载更多
①给ListView添加脚步局 addFooterView()
②监听脚步局控件 加载更多 page++
(2)自动加载更多(隐藏脚步局 inflate.setVisibility(View.GONE))
①自定义 isBottom 判断是否滑倒底部
②给ListView设置滑动监听 setOnScrollListener()
③方法onScroll 根据 firstVisibleItem+visibleItemCount==totalItemCount&&totalItemCount>0
判断是否滑倒底部
方法onScrollStateChanged 根据滑动状态 加载更多
...
lv.setOnScrollListener(new AbsListView.OnScrollListener() { /**
* 滑动状态发生改变:如果滑到底部,加载更多,修改isBottom值
* @param view
* @param scrollState
* //scrollState 有三种类型
* 1.SCROLL_STATE_IDLE 手指未触摸屏幕,且屏幕静止
* 2.SCROLL_STATE_TOUCH_SCROLL 手指未离开屏幕滑动
* 3.SCROLL_STATE_FLING 手指使劲滑动屏幕,然后手指离开屏幕,屏幕仍在滚动
*/ @Override public void onScrollStateChanged(AbsListView view, int scrollState) { switch (scrollState) { case SCROLL_STATE_IDLE: if (isBottom) { page++; initData(); isBottom = false; } break; } } /**
* 滑动监听,判断是否滑动底部,返回isBottom具体值
* @param view
* @param firstVisibleItem:可见页面第一个条目小标
* @param visibleItemCount:可见页面数据个数
* @param totalItemCount:条目总数
*/ @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount > 0) { isBottom = true; } else { isBottom = false; } } });
...
3.Menu 菜单
1》侧滑菜单
①添加依赖
②创建布局:DrawerLayout、NavigationView(三个属性、menu)
③设置actionbar:toolbar设置标题、logo、关联toobar和侧滑菜单
④监听事件:头部监听、侧滑菜单监听(setNavigationItemSelectedListener)、
DrawerLayout (addDrawerListener)、代码开关侧滑菜单
⑤沉浸式状态栏 :fitsSystemWindows="true"
创建文件values-v21 android:statusBarColor: #00ffffff
2》选项菜单
①创建选项菜单(onCreateOptionsMenu):两种方式-代码和menu(showAsAction)
②选项菜单的点击事件(onOptionsItemSelected):switch
3》上下文菜单
①注册上下文菜单:registerForContextMenu()
②创建上下文菜单:onCreateContextMenu()
③上下文菜单点击事件:onContextItemSelected()
注意区别:
OptionsMenu是整个界面共用,ContextMenu是注册给某个组件,此组件拥有此菜单,没有注册的组件没此菜单。
***在Fragment 中如何显示上下文菜单?
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true); //显示上下文菜单
}
4.RecyclerView基本使用
①添加依赖(版本问题注意)
②创建布局(宽高必须是充满的)
③找控件
④设置布局管理器(三种显示方式:线性布局、网格布局、瀑布流布局)
⑤获取数据(切换子线程的方法)
⑥创建适配器-- 重写三个,通过接口回调实现点击事件
⑦设置适配器
1》RecyclerView都布局一:list+banner
① RecyclerView基本使用
②定义类型常量
③重写方法getItemViewType()根据位置返回不同类型
④重写oncreateViewHolder()根据不同类型加载不同的布局
⑤重写onBindViewHolder()根据不用类型加载不同数据
注意:
①获取条目总数:list.size()+1
②onBindViewHolder:获取别表条目数据的时候,position-1
2》RecyclerView多布局二:奇数位置左图右文字+偶数位置左文字右图片
① RecyclerView基本使用(以上)
②定义类型常量
③重写方法getItemViewType()根据位置返回不同类型
④重写oncreateViewHolder()根据不同类型加载不同的布局
⑤重写onBindViewHolder()根据不用类型加载不同数据
3》RecyclerView通过接口回调实现点击事件
①在adapter定义一个内部接口,内部接口定义一个方法,方法参数是我们需要返回值的;
②在adapter定义接口变量,并设置set方法
③在onBindVIewholder()中,给条目做一个点击事件
④在fragment或者activity中,使用adapter对象调用点击事件即可
4》RecyclerView添加刷新
①添加依赖
②在布局中添加刷新的控件并找控件
③给刷新控件添加加载更多、下拉刷新添加监听,监听中写具体代码
④刷新完毕列表,关闭SmartRefreshLayout头和脚。
5.Fragment
1》静态添加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全类名
2》动态添加fragment
...
//获取碎片管理器 FragmentManager fm=getSupportFragmentManager();
//开启事务FragmentTransaction fragmentTransaction=fm.beginTransaction();
//获取fragment对象AFragment aFragment=newAFragment();
//替换容器中内容fragmentTransaction.replace(R.id.fl_container,aFragment);
//提交事务fragmentTransaction.commit();
...
3》 Transaction常用方法
①add
②remove
③replace
④hide
⑤show
⑥attach
⑦detach
⑧commit
4》fragment生命周期
①onAttach()
②onCreate()
③onCreateView()
④onActivityCreated()
⑤onStart()
⑥onResume()
⑦onPause()
⑧onStop()
⑨onDestroyView()
⑩onDestroy()
⑪onDetach()
5》fragment传递数据到activity
①获取activity对象,直接调用方法
MainActivity activity = (MainActivity) getActivity();activity.getMsgFromFramgent("我是来自fragment的数据");
②接口回调传递数据
③通过fragment的有参构造传数据(不推荐)
6》activity传递数据到fragment
①通过bundle方式传值
activity中:
AFragment aFragment=newAFragment();
Bundle bundle=newBundle();
bundle.putString("a","我是来自activity的数据");aFragment.setArguments(bundle);
fragment中:
Bundle bundle=getArguments();String a=bundle.getString("a");
7》fragment与fragment之间传递数据
①通过构造方式传值(不推荐)
②通过FragmentManager找到对应Id或者Tag的Framgment,然后获取里面的数据或方法
③通过它们所在的Activity作为桥梁,可以使用getActivity()或者接口回调,达到获取另一个Fragment数据的目的.
RadioGroup底部导航结合Fragmentr切换
6.ViewPager+tablayout
1》ViewPager结合view实现导航
①创建布局找控件
②获取数据集合
③创建适配器:
getCount()isViewFromObject() instantiateItem()destroyItem()
④设置适配器
2》Viewpager结合Fragment实现导航
①创建布局找控件
②获取fragment的集合fragments
③创建适配器:FragmentStatePagerAdapter和FragmentPagerAdapter区别以及内部方法
④设置适配器
3》Banner开源框架
banner.setBannerStyle(BannerConfig.NUM_INDICATOR_TITLE)//设置风格
.setImages(images)//设置图片集合
.setBannerAnimation(Transformer.DepthPage)//设置动画
.setBannerTitles(titles)//直接添加无效,必须设置BannerStyle
.setImageLoader(newGlideImageLoader())//图片加载器
.start();
4》Tablayout
①属性
5》TVF(TabLayout+ViewPage+Fragment)
①创建布局找控件:TV
②创建两个集合:fragments和titles
③创建适配器:四个方法(包含一个构造)
④设置适配器
⑤TV结合:tab.setupWithViewPager(vp);
⑥设置图片选择器tab.getTabAt(0).setIcon()
Version:1.0StartHTML:000000201EndHTML:000022817StartFragment:000008969EndFragment:000022779StartSelection:000008969EndSelection:000022779SourceURL:https://www.jianshu.com/p/fe890d03854c
7.PopupWindow
①创建PopupWindow布局
②创建PopupWindow对象,用三个参数的构造
③PopupWindow四种显示方式
④聚焦:EditText能输入内容
⑤点击范围外关闭PopupWindow
⑥全屏阴影,PopupWindow点击消失监听
⑦进出场动画
8.Notification
①获取通知管理器getSystemService
②兼容O版以上系统
③获取通知对象(构建者模式):必要属性有三项
④用通知管理器发送通知
⑤延时意图:intent、pendingIntent、setContentIntent
⑥通知提示:声音、震动、呼吸灯、全部
9.权限
分类:
①普通权限:不需要动态获取
②危险权限:需要动态获取
危险权限分类: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.example.contentprovider.ClContentProvider/cl");
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展示音乐列表
②条目点击事件播放对应的音乐
③点击上一首、下一首
...
private void next(){
if(positon<list.size()-1){
positon++;
}else{
positon=0;
}
player(list.get(positon).getPath());
}
private void pre(){
if(positon>0){
positon--;
}else{
positon=list.size()-1;
}
player(list.get(positon).getPath());
}
...