安卓fragment

用途

可以写一个通用的部分,多个Activity来重用.

与activity的关系

一个activity可以使用多个fragment,
一个fragment可以被多个activity使用.
在生命周期上有些关联.

  1. activity.onCreate 外层的activity开始创建
  2. fragment.onAttach 发生关联
  3. fragment.onCreate 开始创建
  4. fragment.onCreateView 专门用于创建view
  5. activity.onStart fragment已经可见,因此activity也可视为创建完毕,开始使用了
  6. fragment.onActivityStart activity可见后fragment自己可做一些处理
  7. activity.onResume 外部的activity先恢复,有时也是onStart之后的动作
  8. fragment.onResume 内部的fragment再恢复

  1. fragment.onStop 内部的fragment先停止
  2. activity.onStop activity再停止

  1. fragment.onDestoryView 销毁view但尚未解除绑定
  2. fragment.onDestory 销毁
  3. fragment.onDetach 解除绑定
  4. activity.onDestory 外层的activity开始销毁

如何定义外观

内部定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class MainFragment : Fragment() {

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return UI {
verticalLayout {
var name = editText("MainUI") {
id = 0x00123
}
button("Say Hello") {
onClick {
ctx.toast("Hello, ${name.text}!")
name.textColor = 0xffff0000.toInt()
}
}
}
}.view
}

}

外部定义

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
class MainActivity2Fragment : Fragment() {

companion object {
fun newInstance() = MainActivity2Fragment()
}

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View = FragmentUi<MainActivity2Fragment>().createView(AnkoContext.create(ctx, this))

}

class FragmentUi<MainActivity2Fragment>: AnkoComponent<MainActivity2Fragment> {
private val ET_ID = 0x0001
override fun createView(ui: AnkoContext<MainActivity2Fragment>) = with(ui) {
verticalLayout {
val name = editText("MainUI") {
id = ET_ID
}
button("Say Hello") {
onClick {
ctx.toast("Hello, ${name.text}!")
name.textColor = 0xffff0000.toInt()
}
}
}
}
}

如何在添加到activity中

1
2
3
4
5
6
7
8
9
10
11
12
class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, MainFragment.newInstance())
.commitNow()
}
}

}

如何在activity中改变fragment中的view

anko好像还没有办法像xml一样使用 +id 来定义新的id

在anko中找到一个view的方法是

  1. 直接使用int来定义新的id.然后使用findviewbyid来寻找
  2. 类中使用延迟初始化的变量,然后将该变量设定值为某一个view元素

因此使用anko在activity中操作fragment元素有几种方法

  1. 使用findviewbyid
  2. fragment自身暴露接口

通过id

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
49
class MainFragment : Fragment() {

companion object {
fun newInstance() = MainFragment()
}

@SuppressLint("ResourceType")
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View = FragmentUi<MainFragment>().createView(AnkoContext.create(ctx, this))

}

class FragmentUi<T>: AnkoComponent<T> {
private val ET_ID = 0x0001
override fun createView(ui: AnkoContext<T>) = with(ui) {
verticalLayout {
val name = editText("MainUI") {
id = ET_ID
}
button("Say Hello") {
onClick {
ctx.toast("Hello, ${name.text}!")
}
}
}
}
}

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)

if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, MainFragment.newInstance())
.commitNow()
}
}

override fun onStart() {
super.onStart()
find<EditText>(0x0001).setText("htahta")
}

}

不定义id,使用延期初始化变量

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
class MainFragment : Fragment() {

lateinit var name: EditText

companion object {
fun newInstance() = MainFragment()
}

private lateinit var viewModel: MainViewModel

@SuppressLint("ResourceType")
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return UI {
verticalLayout {
name = editText("MainUI") {
id = 0x00123
}
button("Say Hello") {
onClick {
ctx.toast("Hello, ${name.text}!")
name.textColor = 0xffff0000.toInt()
}
}
}
}.view
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
// TODO: Use the ViewModel
}

fun updateName(s : String) {
name.setText(s)
}

}

class MainActivity : AppCompatActivity() {
lateinit var mainFragment: MainFragment

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
mainFragment = MainFragment.newInstance()
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, mainFragment)
.commitNow()
}
}

override fun onStart() {
super.onStart()
mainFragment.updateName("ahtaht")
}

}