尝试用kotlin做一个app(十)

写到越后面,渐渐失控

添加子类导航的点击事件

 这是在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上拉刷新下拉加载更多没做。。。

猜你喜欢

转载自www.cnblogs.com/vocus/p/12418182.html
今日推荐