使用 FAB 将数据从 Fragment 传递到 Activity
Pass data from Fragment to Activity with FAB
我有一个 activity 打开,有一个 FAB 按钮,里面有一个片段。主要 activity 有一个带有书籍列表的回收视图。当我点击 fab 时,我打开片段,fab 按钮变成了“关闭片段按钮”,另一个 fab 出现在附近以保存新元素。事实上 fragment 有一些 textview 和 imageview 由用户填充。我的问题是:如何使用保存 fab 按钮将片段上的新元素对象传递给 activity?
主要Activity:
class MainActivity : AppCompatActivity() {
private var recyclerView: RecyclerView? = null
private var classArray: ArrayList<ClassItem>? = null
private var gridLayoutManager: GridLayoutManager? = null
private var classAdapter: ClassAdapter? = null
private var isRotate = true
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(findViewById(R.id.toolbar))
val saveFab = findViewById<FloatingActionButton>(R.id.saveFab)
initFab(saveFab)
saveFab.setOnClickListener{
//I think that I need to do something here
classAdapter?.notifyDataSetChanged()
//Close the fragment
onBackPressed()
}
findViewById<FloatingActionButton>(R.id.fabButton).setOnClickListener {
saveFab.visibility = if(saveFab.visibility == View.VISIBLE) {
View.GONE
} else {
View.VISIBLE
}
/*Animation fab code
....
*/
if(isRotate){
showInFab(saveFab)
supportFragmentManager.open {
// Pass center as the end position of the circular reveal
add(R.id.container, AddClassFragment.newInstance(positions)).addToBackStack(null)
}
} else {
showOutFab(saveFab)
recyclerView?.visibility = View.VISIBLE
findViewById<ImageView>(R.id.imageView2).visibility = View.VISIBLE
with(supportFragmentManager.findFragmentById(R.id.container)) {
// Check if the current fragment implements the [ExitWithAnimation] interface or not
// Also check if the [ExitWithAnimation.isToBeExitedWithAnimation] is `true` or not
if ((this as? ExitWithAnimation)?.isToBeExitedWithAnimation() == true) {
if (this.posX == null || this.posY == null) {
super.onBackPressed()
} else {
this.view?.exitCircularReveal(this.posX!!, this.posY!!) {
super.onBackPressed()
} ?: super.onBackPressed()
}
} else {
super.onBackPressed()
}
}
}
isRotate = rotateFab(it, isRotate)
}
recyclerView = findViewById(R.id.ClassesRecyclerView)
gridLayoutManager = GridLayoutManager(
applicationContext,
1,
LinearLayoutManager.HORIZONTAL,
false
)
recyclerView?.layoutManager = gridLayoutManager
recyclerView?.setHasFixedSize(true)
val snapHelper = LinearSnapHelper()
snapHelper.attachToRecyclerView(recyclerView)
classArray = setClasses()
classAdapter = ClassAdapter(applicationContext, classArray!!)
recyclerView?.adapter = classAdapter
}
override fun onBackPressed() {
//Close fragment or exit app code
}
private fun setClasses(): ArrayList<ClassItem> {
//init the classArray code
}
}
这是片段:
class AddClassFragment: Fragment(), ExitWithAnimation {
override var posX: Int? = null
override var posY: Int? = null
override fun isToBeExitedWithAnimation(): Boolean = true
private var colorAdapter: ChooseColorAdapter? = null
private var recyclerView: RecyclerView? = null
private var colorArray: ArrayList<Int>? = null
private var gridLayoutManager: GridLayoutManager? = null
private var title: TextView? = null
private var colorBook: Int? = null
companion object {
@JvmStatic
fun newInstance(exit: IntArray? = null): AddClassFragment = AddClassFragment().apply {
if (exit != null && exit.size == 2) {
posX = exit[0]
posY = exit[1]
}
}
}
private fun setColor(): ArrayList<Int> {
return arrayListOf(Color.BLACK, Color.CYAN, Color.YELLOW, Color.GREEN, Color.RED, Color.GRAY, Color.MAGENTA, Color.WHITE)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val view: View = inflater.inflate(R.layout.fragment_add_class, container, false)
title = view.findViewById(R.id.title_text_view)
recyclerView = view.findViewById(R.id.colorRecyclerView)
//Grid layout to choose the color of the book
gridLayoutManager = GridLayoutManager(
view.context,
1,
LinearLayoutManager.HORIZONTAL,
false
)
recyclerView?.layoutManager = gridLayoutManager
recyclerView?.setHasFixedSize(true)
colorArray = setColor()
colorAdapter = ChooseColorAdapter(view.context, colorArray!!) {
val bookCover: ImageView = view.findViewById(R.id.add_class_cover_book)
bookCover.setColorFilter(it, PorterDuff.Mode.MULTIPLY)
colorBook = it
}
recyclerView?.adapter = colorAdapter
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.startCircularReveal(false)
}
}
我认为你可以将 saveFab
按钮移动到 AddClassFragment
并添加从 AddClassFragment
到 MainActivity
的回调,例如:
class MainActivity : AppCompatActivity(), AddClassFragment.Listener {
........
override fun saveButtonPressed( data : SomeData){
//Do something with data
println(" Data -> $data")
}
override fun popBackStack(){
classAdapter?.notifyDataSetChanged()
//Close the fragment
onBackPressed()
}
}
class AddClassFragment: Fragment(), ExitWithAnimation {
interface Listener{
fun saveButtonPressed(data: SomeData)
fun popBackStack()
}
private val listener: Listener? = null
override fun onAttach(context: Context) {
super.onAttach(context)
if (context is Listener) {
listener = context
}
}
........
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.startCircularReveal(false)
...
saveFab.setOnClickListener{
val data = getDataFromSomeSource()
listener?.saveButtonPressed(data = data)
listener?.popBackStack()
}
}
}
更新
想法:您可以在片段中创建一个 public 方法,然后使用 supportFragmentManager.findFragmentById()
从 activity 调用它
class 主活动:AppCompatActivity(),AddClassFragment.Listener {
........
override fun onCreate(savedInstanceState: Bundle?) {
........
saveFab.setOnClickListener{
val fragment = supportFragmentManager.findFragmentById(R.id.CONTAINER_ID)
if(fragment != null && fragment is AddClassFragment){
val data = fragment. getDataFromForm()
// do Something with data
println(" Data -> $data")
}
}
}
}
class AddClassFragment: Fragment(), ExitWithAnimation {
........
// this methods return the data after the user filled the
// necessary input
fun getDataFromForm(): SomeData = getDataFromSomeSource()
}
我有一个 activity 打开,有一个 FAB 按钮,里面有一个片段。主要 activity 有一个带有书籍列表的回收视图。当我点击 fab 时,我打开片段,fab 按钮变成了“关闭片段按钮”,另一个 fab 出现在附近以保存新元素。事实上 fragment 有一些 textview 和 imageview 由用户填充。我的问题是:如何使用保存 fab 按钮将片段上的新元素对象传递给 activity?
主要Activity:
class MainActivity : AppCompatActivity() {
private var recyclerView: RecyclerView? = null
private var classArray: ArrayList<ClassItem>? = null
private var gridLayoutManager: GridLayoutManager? = null
private var classAdapter: ClassAdapter? = null
private var isRotate = true
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(findViewById(R.id.toolbar))
val saveFab = findViewById<FloatingActionButton>(R.id.saveFab)
initFab(saveFab)
saveFab.setOnClickListener{
//I think that I need to do something here
classAdapter?.notifyDataSetChanged()
//Close the fragment
onBackPressed()
}
findViewById<FloatingActionButton>(R.id.fabButton).setOnClickListener {
saveFab.visibility = if(saveFab.visibility == View.VISIBLE) {
View.GONE
} else {
View.VISIBLE
}
/*Animation fab code
....
*/
if(isRotate){
showInFab(saveFab)
supportFragmentManager.open {
// Pass center as the end position of the circular reveal
add(R.id.container, AddClassFragment.newInstance(positions)).addToBackStack(null)
}
} else {
showOutFab(saveFab)
recyclerView?.visibility = View.VISIBLE
findViewById<ImageView>(R.id.imageView2).visibility = View.VISIBLE
with(supportFragmentManager.findFragmentById(R.id.container)) {
// Check if the current fragment implements the [ExitWithAnimation] interface or not
// Also check if the [ExitWithAnimation.isToBeExitedWithAnimation] is `true` or not
if ((this as? ExitWithAnimation)?.isToBeExitedWithAnimation() == true) {
if (this.posX == null || this.posY == null) {
super.onBackPressed()
} else {
this.view?.exitCircularReveal(this.posX!!, this.posY!!) {
super.onBackPressed()
} ?: super.onBackPressed()
}
} else {
super.onBackPressed()
}
}
}
isRotate = rotateFab(it, isRotate)
}
recyclerView = findViewById(R.id.ClassesRecyclerView)
gridLayoutManager = GridLayoutManager(
applicationContext,
1,
LinearLayoutManager.HORIZONTAL,
false
)
recyclerView?.layoutManager = gridLayoutManager
recyclerView?.setHasFixedSize(true)
val snapHelper = LinearSnapHelper()
snapHelper.attachToRecyclerView(recyclerView)
classArray = setClasses()
classAdapter = ClassAdapter(applicationContext, classArray!!)
recyclerView?.adapter = classAdapter
}
override fun onBackPressed() {
//Close fragment or exit app code
}
private fun setClasses(): ArrayList<ClassItem> {
//init the classArray code
}
}
这是片段:
class AddClassFragment: Fragment(), ExitWithAnimation {
override var posX: Int? = null
override var posY: Int? = null
override fun isToBeExitedWithAnimation(): Boolean = true
private var colorAdapter: ChooseColorAdapter? = null
private var recyclerView: RecyclerView? = null
private var colorArray: ArrayList<Int>? = null
private var gridLayoutManager: GridLayoutManager? = null
private var title: TextView? = null
private var colorBook: Int? = null
companion object {
@JvmStatic
fun newInstance(exit: IntArray? = null): AddClassFragment = AddClassFragment().apply {
if (exit != null && exit.size == 2) {
posX = exit[0]
posY = exit[1]
}
}
}
private fun setColor(): ArrayList<Int> {
return arrayListOf(Color.BLACK, Color.CYAN, Color.YELLOW, Color.GREEN, Color.RED, Color.GRAY, Color.MAGENTA, Color.WHITE)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val view: View = inflater.inflate(R.layout.fragment_add_class, container, false)
title = view.findViewById(R.id.title_text_view)
recyclerView = view.findViewById(R.id.colorRecyclerView)
//Grid layout to choose the color of the book
gridLayoutManager = GridLayoutManager(
view.context,
1,
LinearLayoutManager.HORIZONTAL,
false
)
recyclerView?.layoutManager = gridLayoutManager
recyclerView?.setHasFixedSize(true)
colorArray = setColor()
colorAdapter = ChooseColorAdapter(view.context, colorArray!!) {
val bookCover: ImageView = view.findViewById(R.id.add_class_cover_book)
bookCover.setColorFilter(it, PorterDuff.Mode.MULTIPLY)
colorBook = it
}
recyclerView?.adapter = colorAdapter
return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.startCircularReveal(false)
}
}
我认为你可以将 saveFab
按钮移动到 AddClassFragment
并添加从 AddClassFragment
到 MainActivity
的回调,例如:
class MainActivity : AppCompatActivity(), AddClassFragment.Listener {
........
override fun saveButtonPressed( data : SomeData){
//Do something with data
println(" Data -> $data")
}
override fun popBackStack(){
classAdapter?.notifyDataSetChanged()
//Close the fragment
onBackPressed()
}
}
class AddClassFragment: Fragment(), ExitWithAnimation {
interface Listener{
fun saveButtonPressed(data: SomeData)
fun popBackStack()
}
private val listener: Listener? = null
override fun onAttach(context: Context) {
super.onAttach(context)
if (context is Listener) {
listener = context
}
}
........
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.startCircularReveal(false)
...
saveFab.setOnClickListener{
val data = getDataFromSomeSource()
listener?.saveButtonPressed(data = data)
listener?.popBackStack()
}
}
}
更新
想法:您可以在片段中创建一个 public 方法,然后使用 supportFragmentManager.findFragmentById()
class 主活动:AppCompatActivity(),AddClassFragment.Listener {
........
override fun onCreate(savedInstanceState: Bundle?) {
........
saveFab.setOnClickListener{
val fragment = supportFragmentManager.findFragmentById(R.id.CONTAINER_ID)
if(fragment != null && fragment is AddClassFragment){
val data = fragment. getDataFromForm()
// do Something with data
println(" Data -> $data")
}
}
}
}
class AddClassFragment: Fragment(), ExitWithAnimation {
........
// this methods return the data after the user filled the
// necessary input
fun getDataFromForm(): SomeData = getDataFromSomeSource()
}