使用 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 并添加从 AddClassFragmentMainActivity 的回调,例如:

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()    
}