写到越后面,渐渐失控
添加子类导航的点击事件
这是在pagerview中嵌套了layout布局。三个子控件属于layout布局,给它们添加点击事件,直接用它们的控件id就好
但是如果在homepagefragment类中直接id.setOnClickListener{}就会报Unable to start activity ComponentInfo{com.vocus.justtest/com.vocus.justtest.ui.activity.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method ‘void com.vocus.justtest.view.ImageTextView估计是上下文的问题吧
那就在adapter中去设置吧
when (position%3) { 0 -> { var navView = LayoutInflater.from(container.context) .inflate(R.layout.fragment_home_nav_program, container, false) container.addView(navView) // var javaView=navView.findViewById<ImageTextView>(R.id.nav_item_java); javaView.setOnClickListener{ Toast.makeText(container.context,"点击了", Toast.LENGTH_SHORT).show() } var kotlinView=navView.findViewById<ImageTextView>(R.id.nav_item_kotlin); kotlinView.setOnClickListener{ Toast.makeText(container.context,"点击了", Toast.LENGTH_SHORT).show() } var cView=navView.findViewById<ImageTextView>(R.id.nav_item_c); cView.setOnClickListener{ Toast.makeText(container.context,"点击了", Toast.LENGTH_SHORT).show() } return navView }
点击要跳转到新的页面,与此同时还应该把点击了哪个view的标识传过去。本来想把view的文本传过去,但是有可能是中文,就不太方便了,还是传个位置过去吧,比如
var javaView=navView.findViewById<ImageTextView>(R.id.nav_item_java);
var intent:Intent?=null;
intent= Intent(container.context,NewsListActivity::class.java)
javaView.setOnClickListener{
intent.putExtra("position",0);
container.context.startActivity(intent)
}
子类导航的文章列表
布局是一个toolbar和一个recyclerview
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <include layout="@layout/toolbar"/> <androidx.recyclerview.widget.RecyclerView android:id="@+id/rv_newslist" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp"/> </LinearLayout>
toolbar布局包括显示标题,一个返回按钮和一个菜单
<Toolbar android:id="@+id/toolbar" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#3EA3C7" android:navigationIcon="@drawable/ic_back2"> <!-- #E56B6B--> <TextView android:id="@+id/toolbar_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="编程语言" android:textSize="20dp" android:textColor="#fff"/> </Toolbar>
toolbar因为在别的地方也会用到,所以建个管理接口ToolbarManager
interface ToolbarManager { val toolbar:Toolbar val activity:Activity fun initNavDetailToolbar(){ toolbar.title="" toolbar.setTitleTextColor(Color.WHITE) toolbar.inflateMenu(R.menu.list) toolbar.setOnMenuItemClickListener(object :Toolbar.OnMenuItemClickListener{ override fun onMenuItemClick(p0: MenuItem?): Boolean { when(p0?.itemId){ // } return true } }) toolbar.setNavigationOnClickListener(View.OnClickListener{ activity.finish() } ) //高度设置 var statusbarTool=StatusbarTool() var statusHeight=statusbarTool.getStatusbarHeight(activity) //(toolbar.layoutParams as ViewGroup.MarginLayoutParams).topMargin=stateHeight toolbar.setPadding(0,statusHeight,0,0) }
菜单布局
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/setting" android:title="设置" android:icon="@drawable/dot1" android:showAsAction="always" /> </menu>
NewsListActivity中
class NewsListActivity:BaseActivity() ,ToolbarManager{ override val toolbar: Toolbar by lazy{ findViewById<Toolbar>(R.id.toolbar) } override val activity:Activity=this override fun getLayoutId(): Int { return R.layout.newslist; } override fun initData() { initNavDetailToolbar() var statusbarTool=StatusbarTool() statusbarTool.makeStatusBarTransparent(this) //RecyclerView rv_newslist.layoutManager=LinearLayoutManager(baseContext) var adapter=NewsListAdapter() rv_newslist.adapter=adapter } }
statusbarTool是我自己封装的关于状态栏的工具类,包括获得状态栏高度,设置状态栏透明。关于状态栏,第四篇有分析过
在设置toolbar的时候遇到的几个问题和解决办法
菜单图标不显示,命名空间的问题,我把showAsAction设置为android前缀了。参考Android 4.3 menu item showAsAction=“always” ignored
还有个问题也有必要处理一下的,就是设置状态栏透明之后,toolbar和状态栏重合了。这个问题之前遇到过,那我现在不考虑兼容的问题,给toolbar设置一个状态栏高度的padding
toolbar.setPadding(0,statusHeight,0,0)
RecyclerView的话随便写个就好了。最后静态的效果是这样的
还有一个问题,点击右上角的菜单,会弹出一个对话框
自定义一个Dialog就行。因为需要让对话框去掉左右边距,并且底部对齐,所以样定义它的样式
<style name="BottomUpDialog" parent="@android:style/Theme.Dialog"> <item name="android:windowNoTitle">true</item> <item name="android:windowBackground">@android:color/transparent</item> </style>
似乎只有设置了android:windowBackground为透明,才能让它底部对齐。一旦设置背景透明,dialog里的控件如果使用padding,padding也会透明。所以只好为控件设置固定高度了。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="fill_parent" android:orientation="vertical"> <Button android:layout_width="match_parent" android:layout_height="40dp" android:text="关注" android:background="#ffffff" /> <ImageView android:layout_width="match_parent" android:layout_height="0.5dp" android:background="#D9D9D9"/> <Button android:layout_width="match_parent" android:layout_height="40dp" android:text="取消" android:background="#ffffff" /> </LinearLayout>
Dialog类
class BottomUpDialog : Dialog { constructor(context: Context):super(context,R.style.BottomUpDialog) constructor(context: Context,themerResId:Int):super(context,themerResId) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.dialog_bottomup) initView() } private fun initView() { //宽度填充屏幕 window?.decorView?.setPadding(0,0,0,0) // window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT) var attr=window?.attributes attr?.width= WindowManager.LayoutParams.MATCH_PARENT; attr?.height= WindowManager.LayoutParams.WRAP_CONTENT; //底部对齐 attr?.gravity=Gravity.BOTTOM window?.attributes=attr //底部对齐 //window?.setGravity(Gravity.BOTTOM) } }
还有要设置一下边框的样式,上面显示一个圆角表框
定义边框的样式
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <shape> <solid android:color="#D9D9D9" /> <corners android:topLeftRadius="20dp" android:topRightRadius="20dp"/> </shape> </item> <item android:top="0.5dp"> <shape> <solid android:color="#ffffff" /> <corners android:topLeftRadius="10dp" android:topRightRadius="10dp"/> </shape> </item> </layer-list>
参考:Android中如何让控件只显示某一边框,在第一个textView上使用这个边框样式
弹出对话框还要加个动画属性,让显示的时候从下至上弹出,隐藏的时候从下往上隐藏
定义两个动画资源,然后这样引用就行
<style name="BottomUpDialog" parent="@android:style/Theme.Dialog"> <item name="android:windowNoTitle">true</item> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:windowAnimationStyle">@style/dialogAnim</item> </style> <style name="dialogAnim" parent="@android:style/Animation.Dialog"> <item name="android:windowEnterAnimation">@anim/dialog_enter_anim</item> <item name="android:windowExitAnimation">@anim/dialog_exit_anim</item> </style>
然后就是响应dialog中按钮的点击事件
就设置一下按钮点击监听就好了
dialog_follow.setOnClickListener {
}
dialog_cancel.setOnClickListener {
dismiss()
}
最后我还想做一个功能
从首页导航跳转到文章列表页,根据选择的项目不同,动态设置一下toolbar的标题和背景颜色
在ToolBarManager中定义一个函数
fun setNavDetalToolbarStyle(title:String,color:Int){ toolbar.setBackgroundColor(color) toolbar.toolbar_title.text=title }
然后在NewsListActivity初始化函数中执行函数。。
如果getStringExtra为空,参考Android Kotlin intent.getStringExtra("xxx") 获取为 null 问题解决
override fun initData() { initNavDetailToolbar() var pos:Int=intent.getStringExtra("posi").toInt() when(pos){ 0->setNavDetalToolbarStyle("JAVA", Color.RED) 1->setNavDetalToolbarStyle("Kotlin",Color.GREEN) 2->setNavDetalToolbarStyle("C/C++",Color.BLUE) } // var statusbarTool=StatusbarTool() statusbarTool.makeStatusBarTransparent(this) //RecyclerView rv_newslist.layoutManager=LinearLayoutManager(baseContext) var adapter=NewsListAdapter() rv_newslist.adapter=adapter } }
暂时就这样吧,我累。。效果
还有RecyclerView上拉刷新下拉加载更多没做。。。