1.效果预览
1.1.如下图所以,到目前为止所有的功能。
2.从InitApp开始->SplashActivity->MainActivity
2.1.InitApp源代码。这是整个项目的Application。
public class InitApp extends MultiDexApplication { public static Context AppContext; @Override public void onCreate(){ super.onCreate(); AppContext=getApplicationContext(); //初始化主题 initTheme(); //错误日志分析 CrashHandlerUtil.getInstance().init(AppContext); if(BuildConfig.DEBUG){ SDKManager.initStetho(AppContext); } } private void initTheme(){ } }
2.2.启动页面SplashActivity
class SplashActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val intent= Intent(this, MainActivity::class.java) startActivity(intent) finish() } }
2.3.主页面MainActivity
class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedListener { companion object { private val TAG="MainActivity" private val POSITION="position" private val SELECT_ITEM="bottomNavigationSelectItem" private val FRAGMENT_NEWS=0 private val FRAGMENT_PHOTO=1 private val FRAGMENT_VIDEO=2 private val FRAGMENT_MEDIA=3 private val REQUEST_EXTERNAL_STORAGE = 1 private val PERMISSIONS_STORAGE = arrayOf("android.permission.READ_EXTERNAL_STORAGE", "android.permission.WRITE_EXTERNAL_STORAGE") } private var newsTabLayout: NewsTabLayout?=null //新闻布局 private var photoTabLayout: PhotoTabLayout?=null //图片布局 private var videoTabLayout: VideoTabLayout?=null //视频布局 private var mediaChannelView: MediaChannelView?=null //头条号布局 private var toolbar: Toolbar?=null //标题栏 private var bottom_navigation:BottomNavigationView?=null private var exitTime:Long=0 private var position:Int=0 private var firstClickTime:Long=0 private var nav_view:NavigationView?=null private var drawer_layout:DrawerLayout?=null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) initView() verifyStoragePermissions(this) if(savedInstanceState!=null){ newsTabLayout=supportFragmentManager!!.findFragmentByTag(NewsTabLayout::class.java.name) as NewsTabLayout photoTabLayout=supportFragmentManager!!.findFragmentByTag(PhotoTabLayout::class.java.name) as PhotoTabLayout videoTabLayout=supportFragmentManager!!.findFragmentByTag(VideoTabLayout::class.java.name) as VideoTabLayout mediaChannelView=supportFragmentManager!!.findFragmentByTag(MediaChannelView::class.java.name) as MediaChannelView //恢复 recreate 前的位置 showFragment(savedInstanceState.getInt(POSITION)) bottom_navigation!!.selectedItemId=savedInstanceState.getInt(SELECT_ITEM) }else{ showFragment(FRAGMENT_NEWS) } if(SettingUtil.getInstance().getIsFirstTime()){ showTapTarget() } } private fun showTapTarget(){ val display=windowManager.defaultDisplay val target=Rect(0,display.height,0,display.height) target.offset(display.width/8,-56) val sequence=TapTargetSequence(this) .targets( TapTarget.forToolbarMenuItem(toolbar!!,R.id.action_search,"点击这里进行搜索") .dimColor(android.R.color.black) .outerCircleColor(R.color.colorPrimary) .drawShadow(true) .id(1), TapTarget.forToolbarNavigationIcon(toolbar!!,"点击这里展开侧栏") .dimColor(android.R.color.black) .outerCircleColor(R.color.colorPrimary) .drawShadow(true) .id(2), TapTarget.forBounds(target,"点击这里切换新闻\n再次点击刷新当前页面") .dimColor(android.R.color.black) .outerCircleColor(R.color.colorPrimary) .targetRadius(60) .transparentTarget(true) .drawShadow(true) .id(3) ).listener(object:TapTargetSequence.Listener{ override fun onSequenceFinish() { SettingUtil.getInstance().isFirstTime=false } override fun onSequenceStep(lastTarget: TapTarget?, targetClicked: Boolean) { } override fun onSequenceCanceled(lastTarget: TapTarget?) { } }) sequence.start() } override fun initSlidable() { //禁止滑动返回 //什么都不写就行了 } override fun onSaveInstanceState(outState: Bundle?) { outState!!.putInt(POSITION,position) outState!!.putInt(SELECT_ITEM,bottom_navigation!!.selectedItemId) } private fun initView(){ toolbar=findViewById(R.id.toolbar) as Toolbar toolbar!!.inflateMenu(R.menu.menu_activity_main) bottom_navigation=findViewById(R.id.bottom_navigation) as BottomNavigationView //解决只有图标没有文字的问题 BottomNavigationViewHelper.disableShiftMode(bottom_navigation) setSupportActionBar(toolbar) setTitle(R.string.title_news) bottom_navigation!!.setOnNavigationItemSelectedListener{ item -> when(item.itemId){ R.id.action_news -> { showFragment(FRAGMENT_NEWS) doubleClick(FRAGMENT_NEWS) } R.id.action_photo -> { showFragment(FRAGMENT_PHOTO) doubleClick(FRAGMENT_PHOTO) } R.id.action_video -> { showFragment(FRAGMENT_VIDEO) doubleClick(FRAGMENT_VIDEO) } R.id.action_media -> { showFragment(FRAGMENT_MEDIA) } } true } drawer_layout=findViewById(R.id.drawer_layout) as DrawerLayout val toggle=ActionBarDrawerToggle(this,drawer_layout,toolbar,R.string.navigation_drawer_open,R.string.navigation_drawer_close) drawer_layout!!.addDrawerListener(toggle) toggle.syncState() nav_view=findViewById(R.id.nav_view) as NavigationView nav_view!!.setNavigationItemSelectedListener(this) } fun doubleClick(index:Int){ val secondClickTime=System.currentTimeMillis() if((secondClickTime-firstClickTime)<500){ when(index){ FRAGMENT_NEWS -> { } FRAGMENT_PHOTO ->{ } FRAGMENT_VIDEO -> { } } }else{ firstClickTime=secondClickTime } } private fun showFragment(index:Int){ val ft=supportFragmentManager.beginTransaction() hideFragment(ft) position=index when(index){ FRAGMENT_NEWS -> { toolbar!!.setTitle(R.string.title_news) if(newsTabLayout==null){ newsTabLayout = NewsTabLayout.getInstance() ft.add(R.id.container, newsTabLayout, NewsTabLayout::class.java.name) }else{ ft.show(newsTabLayout) } } FRAGMENT_PHOTO -> { toolbar!!.setTitle(R.string.title_photo) if(photoTabLayout==null){ photoTabLayout = PhotoTabLayout.getInstance() ft.add(R.id.container, photoTabLayout, PhotoTabLayout::class.java.name) }else{ ft.show(photoTabLayout) } } FRAGMENT_VIDEO -> { toolbar!!.setTitle(R.string.title_video) if(videoTabLayout==null){ videoTabLayout = VideoTabLayout.getInstance() ft.add(R.id.container, videoTabLayout, VideoTabLayout::class.java.name) }else{ ft.show(videoTabLayout) } } FRAGMENT_MEDIA -> { toolbar!!.setTitle(R.string.title_media) if(mediaChannelView==null){ }else{ } } } ft.commit() } private fun hideFragment(ft:FragmentTransaction){ //如果不为空,就先隐藏起来 if(newsTabLayout!=null){ ft.hide(newsTabLayout) } if(photoTabLayout!=null){ ft.hide(photoTabLayout) } if(videoTabLayout!=null){ ft.hide(videoTabLayout) } if(mediaChannelView!=null){ ft.hide(mediaChannelView as Fragment) } } override fun onBackPressed() { //再次点击退出 val currentTime=System.currentTimeMillis() if((currentTime-exitTime)<2000){ super.onBackPressed() }else{ Toast.makeText(this,R.string.double_click_exit,Toast.LENGTH_SHORT).show() exitTime=currentTime } } override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_activity_main, menu) return true } override fun onOptionsItemSelected(item: MenuItem): Boolean { if (item.itemId == R.id.action_search) { //跳转到搜索页面 } return super.onOptionsItemSelected(item) } override fun onNavigationItemSelected(item: MenuItem): Boolean { // val id=item.itemId when(id){ R.id.nav_switch_night_mode ->{ } R.id.nav_setting ->{ } R.id.nav_share -> { } } return false } fun verifyStoragePermissions(activity: Activity) { try { //检测是否有写的权限 val permission = ActivityCompat.checkSelfPermission(activity, "android.permission.WRITE_EXTERNAL_STORAGE") if (permission != PackageManager.PERMISSION_GRANTED) { // 没有写的权限,去申请写的权限,会弹出对话框 ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE) } } catch (e: Exception) { e.printStackTrace() } } }
2.4.MainActivity布局
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:andro>
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start"
>
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<include layout="@layout/toolbar"/>
<include layout="@layout/container"/>
<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation"
style="@style/Widget.Design.BottomNavigationView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
android:background="@color/viewBackground"
app:elevation="16dp"
app:itemIconTint="@drawable/nav_item_color_state"
app:itemTextColor="@drawable/nav_item_color_state"
app:menu="@menu/bottom_navigation_main"
/>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/nav_menu"
/>
</android.support.v4.widget.DrawerLayout>
@layout/toolbar布局
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/AppBarLayout01" android:layout_width="match_parent" android:layout_height="wrap_content" android:fitsSystemWindows="false" android:theme="@style/AppTheme.AppBarOverlay" app:elevation="0dp" > <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:layout_scrollFlags="scroll|enterAlways" app:popupTheme="@style/AppTheme.PopupOverlay" /> </android.support.design.widget.AppBarLayout>