自定义封装控件的依赖库

Posted by kirito on 2020-11-28

基于GridLayout封装的自定义依赖库控件ScheduleView

Git地址

效果图

简单实现日程表,同时实现多种不同的子布局,支持自定义layout
在这里插入图片描述

添加依赖库

Add it in your root build.gradle at the end of repositories:

1
2
3
4
5
6
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}

Add the dependency:

1
2
3
dependencies {
implementation 'com.github.kirito0206:ScheduleView:1.0.2'
}

使用方式

在XML文件中添加

1
2
3
4
5
6
<com.example.scheduleview.ScheduleView
android:id="@+id/sv_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:rowCount="12"
android:columnCount="8"/>

设置适配器类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/*
可以传入数据类、横坐标Title、纵坐标Title的list
数据类需要实现获取对应的x、y范围
*/
class SVAdapter(val context : Context,val list: ArrayList<T>) : ScheduleAdapter() {

//返回日程表中的item数
override fun getItemCount(): Int {
return list.size
}

//获取item对应的横坐标
override fun getDay(position: Int): Int {
return list[position].day
}

//获取item对应的纵坐标范围
override fun getBoundary(position: Int): Pair<Int, Int> {
return Pair(list[position].timeX, list[position].timeY)
}

//设置item的布局样式,返回对应view
override fun getView(position: Int): View {
//子布局只有单一控件,如TextView、EditView、ImageView等
//可以像如下设置
val textView = TextView(context)
textView.text = position.toString()
textView.gravity = Gravity.CENTER
return textView
//自己创建layout,如下进行初始化
val inflater = LayoutInflater.from(context)
var view = inflater.inflate(R.layout.item_schedule, null)
//view.textview.text = "内容"...
view.foregroundGravity = Gravity.CENTER
return view
}

//设置横坐标Title
override fun getXTitle(dayIndex: Int): String {
return "XTitle"
}

//设置纵坐标Title
override fun getYTitle(timeIndex: Int): String {
return "YTitle"
}

}

然后在代码中初始化view即可

1
2
3
4
5
var adapter = SVAdapter(this,list)
sv_main.adapter = adapter
sv_main.post {
sv_main.show()
}

项目局部实现方式

封装适配器基类,方便获取数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
abstract class ScheduleAdapter {

abstract fun getItemCount() : Int

abstract fun getDay(position: Int) : Int

abstract fun getBoundary(position : Int) : Pair<Int,Int>

abstract fun getView(position: Int) : View

abstract fun getXTitle(position: Int) : String

abstract fun getYTitle(position: Int) : String
}

Gridlayout动态添加自定义的布局(困扰了很久

因为xml中的wrap_content和match_parent无效

所以采用view调用post的方法(所有view绘制结束后进行,就可以获取到宽高),再进行添加子布局

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//在scheduleview中,调用adapter获取所需的对应数据
for (i in 0 until adapter!!.getItemCount()){
var t = adapter!!.getBoundary(i)
//设置所占行列
val rowSpec: Spec =
spec(t.first, t.second - t.first +1)
val columnSpec = spec(adapter!!.getDay(i), 1)
val params =
LayoutParams(rowSpec, columnSpec)
params.width = (this.width-48)/columnCount
params.height = (this.height-48)/rowCount * (t.second - t.first +1)
params.setMargins(5,5,5,5)
params.setGravity(Gravity.CENTER and Gravity.FILL)
this.addView(adapter!!.getView(i),params)
}