为什么一次在Spinner中显示两个项目?

时间:2018-03-28 16:44:14

标签: android kotlin spinner dropdown android-moxy

我的一个下拉列表中的项目由于某种原因在方向更改后开始加倍。

这是两张照片:一张有虫子(换成水平和背面后),另一张没有。

Bug picture How it should be

这是我的代码:

活动类:

class ScheduleActivity : AppCompatActivity(), GroupPickerActivity {
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_lessons_list)

    val groupPickerFragment = GroupPickerFragment()

    fragmentManager.beginTransaction()
            .add(R.id.central_frame, groupPickerFragment)
            .commit()
}

override fun finishPicking() {
    Toast.makeText(applicationContext, "Finished picking", Toast.LENGTH_SHORT).show()
}
}

片段类:

class GroupPickerFragment : MvpFragment(), GroupPickerView {

    val TAG = "GroupPickerFragment"

    @InjectPresenter
    lateinit var groupPickerPresenter: GroupPickerPresenter

    var noCitySelected = true
    var noSchoolSelected = true
    var noGroupSelected = true

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {

        return inflater!!.inflate(R.layout.fragment_group_picker, container, false)
    }


    override fun onStart() {
        super.onStart()

        groupPickerPresenter.start(activity.applicationContext)

        makeCitySpinnerClickable()
    }

    private fun makeCitySpinnerClickable() {
        /*
        * Set onItemSelectedListener on City picker spinner
        * */

        pick_your_city_tv.visibility = View.VISIBLE
        city_picker_spinner.visibility = View.VISIBLE

        city_picker_spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(parentView: AdapterView<*>, selectedItemView: View?, pos: Int, id: Long) {
                if (!noCitySelected) {
                    val selectedItem = parentView.getItemAtPosition(pos)

                    if (pos != 0) {
                        onCitySelected(selectedItem.toString())
                    } else {
                        onCreateNewCitySelected()
                    }
                } else {
                    noCitySelected = false
                }

            }

            override fun onNothingSelected(parentView: AdapterView<*>?) {}
        }
    }

    private fun onCreateNewCitySelected() {

        val textbox = EditText(activity.applicationContext)

        val alertDialogBuilder = AlertDialog.Builder(activity,
                R.style.AppTheme_myDialogueWindow)

        alertDialogBuilder.setTitle(R.string.enter_new_city_name)
                .setCancelable(true)
                .setView(textbox)
                .setPositiveButton(R.string.create_new, { _, _ ->
                    val newCityName = textbox.text.toString()

                    if (newCityName != "") {
                        groupPickerPresenter.createNewCity(newCityName)
                    } else {
                        Toast.makeText(activity.applicationContext,
                                R.string.city_name_cannot_be_empty,
                                Toast.LENGTH_SHORT).show()
                    }
                })
                .show()
    }

    override fun onCitiesDownloaded(cityList: ArrayAdapter<String>) {
        val spinner = city_picker_spinner

        val adapter = cityList
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)

        spinner.adapter = adapter

    }

    fun onCitySelected(cityName: String) {
        Log.v(TAG, "Get cities by name")

        groupPickerPresenter.onCitySelected(cityName)
        makeSchoolSpinnerClickable()

    }

    override fun onCityAdded(newCityId: String) {
        groupPickerPresenter.start(activity.applicationContext)
    }

    override fun onSchoolsDownloaded(schoolsList: ArrayAdapter<String>) {
        val spinner = school_picker_spinner

        val adapter = schoolsList
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)

        spinner.adapter = adapter

    }

    private fun makeSchoolSpinnerClickable() {
        /*
        * Set onItemSelectedListener on School picker spinner
        * */

        pick_your_school_tv.visibility = View.VISIBLE
        school_picker_spinner.visibility = View.VISIBLE

        school_picker_spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(parentView: AdapterView<*>, selectedItemView: View?, pos: Int, id: Long) {
                if (!noSchoolSelected) {
                    val selectedItem = parentView.getItemAtPosition(pos)

                    if (pos != 0) {
                        onSchoolSelected(selectedItem.toString())
                    } else {
                        onCreateNewSchoolSelected()
                    }
                } else {
                    noSchoolSelected = false
                }

            }

            override fun onNothingSelected(parentView: AdapterView<*>?) {}
        }
    }

    private fun onCreateNewSchoolSelected() {
        val textbox = EditText(activity.applicationContext)

        val alertDialogBuilder = AlertDialog.Builder(activity,
                R.style.AppTheme_myDialogueWindow)

        alertDialogBuilder.setTitle(R.string.enter_new_school_name)
                .setCancelable(true)
                .setView(textbox)
                .setPositiveButton(R.string.create_new, { _, _ ->
                    val newSchoolName = textbox.text.toString()

                    if (newSchoolName != "") {
                        val cityName = city_picker_spinner.selectedItem.toString()

                        groupPickerPresenter.createNewSchool(newSchoolName, cityName)

                    } else {
                        Toast.makeText(activity.applicationContext,
                                R.string.school_name_cannot_be_empty,
                                Toast.LENGTH_SHORT).show()
                    }
                })
                .show()
    }

    private fun onSchoolSelected(schoolName: String) {
        Log.v(TAG, "Get schools by name")

        groupPickerPresenter.onSchoolSelected(schoolName)

        makeGroupSpinnerClickable()
    }

    override fun onSchoolAdded(newCityId: String) {
        //todo Когда новая школа добавлена, надо обновить список школ
    }

    override fun onGroupsDownloaded(groupsList: ArrayAdapter<String>) {
        val spinner = group_picker_spinner

        val adapter = groupsList
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)

        spinner.adapter = adapter

    }

    private fun makeGroupSpinnerClickable() {
        /*
        * Set onItemSelectedListener on School picker spinner
        * */

        pick_your_group_tv.visibility = View.VISIBLE
        group_picker_spinner.visibility = View.VISIBLE


        group_picker_spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(parentView: AdapterView<*>, selectedItemView: View?, pos: Int, id: Long) {
                if (!noGroupSelected) {
                    val selectedItem = parentView.getItemAtPosition(pos)

                    if (pos != 0) {
                        onGroupSelected(selectedItem.toString())
                    } else {
                        onCreateNewGroupSelected()
                    }
                } else {
                    noGroupSelected = false
                }

            }

            override fun onNothingSelected(parentView: AdapterView<*>?) {}
        }
    }

    private fun onGroupSelected(groupName: String) {
        groupPickerPresenter.onGroupSelected(groupName)
    }

    private fun onCreateNewGroupSelected() {
        val textbox = EditText(activity.applicationContext)

        val alertDialogBuilder = AlertDialog.Builder(activity,
                R.style.AppTheme_myDialogueWindow)

        alertDialogBuilder.setTitle(R.string.enter_new_group_name)
                .setCancelable(true)
                .setView(textbox)
                .setPositiveButton(R.string.create_new, { _, _ ->
                    val newGroupName = textbox.text.toString()

                    if (newGroupName != "") {
                        val schoolName = school_picker_spinner.selectedItem.toString()

                        groupPickerPresenter.createNewGroup(newGroupName, schoolName)

                    } else {
                        Toast.makeText(activity.applicationContext,
                                R.string.group_name_cannot_be_empty,
                                Toast.LENGTH_SHORT).show()
                    }
                })
                .show()
    }

    override fun onGroupAdded(updatedSchoolId: String) {
        //todo обновить список групп
    }

    override fun letUserContinue() {
        group_picker_next_btn.isEnabled = true
        group_picker_next_btn.setOnClickListener({
            val selectedSchoolName = school_picker_spinner.selectedItem.toString()
            val selectedGroupName = group_picker_spinner.selectedItem.toString()

            groupPickerPresenter.pick(selectedSchoolName, selectedGroupName)

            group_picker_progressbar.visibility = View.VISIBLE
        })
    }

    override fun finishPicking() {
        group_picker_progressbar.visibility = View.GONE
        (activity as GroupPickerActivity).finishPicking()
    }
}

片段控制器类:

@InjectViewState
class GroupPickerPresenter : MvpPresenter<GroupPickerView>() {
    val TAG = "GroupPickerPresenter"

    val cityModel = CityFirestoreModel()
    val schoolModel = SchoolFirestoreModel()

    lateinit var context: Context

    init {

    }

    fun start(context: Context) {
        this.context = context

        getCities()
    }

    private fun getCities() {
        cityModel.getAllCities {
            val cityTitlesList = mutableListOf<String>()

            // Adding 'Create new'
            cityTitlesList.add(this.context.resources.getString(R.string.create_new))

            it.forEach {
                cityTitlesList.add(it.title)
            }

            val arrayAdapter = ArrayAdapter<String>(this.context,
                    android.R.layout.simple_spinner_item, cityTitlesList)


            viewState.onCitiesDownloaded(arrayAdapter)
        }

    }

    fun createNewCity(newCityName: String) {
        cityModel.addCity(newCityName, { newCityId ->
            if (newCityId != null)
                viewState.onCityAdded(newCityId)
        })
    }

    fun onCitySelected(cityName: String) {
        val cityModel = CityFirestoreModel()

        cityModel.getCitiesByName(cityName, {
            getSchoolsByCity(it)
        })
    }

    private fun getSchoolsByCity(cities: MutableList<City>) {
        val schoolModel = SchoolFirestoreModel()

        if (cities.size > 0) {
            val city = cities[0]

            schoolModel.getSchoolsByCityName(city.title, {
                val schoolTitlesList = mutableListOf<String>()

                // Adding 'Create new'
                schoolTitlesList.add(this.context.resources.getString(R.string.create_new))

                it.forEach {
                    schoolTitlesList.add(it.title)
                }

                val arrayAdapter = ArrayAdapter<String>(this.context,
                        android.R.layout.simple_spinner_item, schoolTitlesList)

                viewState.onSchoolsDownloaded(arrayAdapter)
            })
        } else {
            Log.e(TAG, "Cities list is empty")

            val schoolTitlesList = mutableListOf<String>()

            // Adding 'Create new'
            schoolTitlesList.add(this.context.resources.getString(R.string.create_new))

            val arrayAdapter = ArrayAdapter<String>(this.context,
                    android.R.layout.simple_spinner_item, schoolTitlesList)

            viewState.onSchoolsDownloaded(arrayAdapter)
        }

    }

    fun onSchoolSelected(schoolName: String) {
        val schoolModel = SchoolFirestoreModel()

        schoolModel.getSchoolGroups(schoolName, {
            val groupTitlesList = mutableListOf<String>()

            // Adding 'Create new'
            groupTitlesList.add(this.context.resources.getString(R.string.create_new))

            it.forEach {
                groupTitlesList.add(it.title)
            }

            val arrayAdapter = ArrayAdapter<String>(this.context,
                    android.R.layout.simple_spinner_item, groupTitlesList)

            viewState.onGroupsDownloaded(arrayAdapter)
        })
    }

    fun createNewSchool(newSchoolName: String, cityName: String) {
        val city = City()
        city.title = cityName

        val teachers = mutableListOf<Teacher>()
        val subjects = mutableListOf<Subject>()
        val groups = mutableListOf<Group>()


        schoolModel.addSchool(newSchoolName, city, teachers, subjects, groups, { newCityId ->
            if (newCityId != null)
                viewState.onSchoolAdded(newCityId)
        })
    }

    fun onGroupSelected(groupName: String) {
        viewState.letUserContinue()
    }

    fun createNewGroup(newGroupName: String, schoolName: String) {
        schoolModel.getSchoolsByName(schoolName, {
            val school = it[0] //todo сделать какую-то проверку на уникальность, чтоб не было проблем

            val group = Group()
            group.title = newGroupName

            school.groups.add(group)

            schoolModel.updateSchool(school.school_id, school, {updatedSchoolId ->
                if (updatedSchoolId != null) {
                    viewState.onGroupAdded(updatedSchoolId)
                }
            })
        })
    }

    fun pick(schoolName: String, groupName: String) {
        val schoolModel = SchoolFirestoreModel()

        schoolModel.getSchoolGroup(schoolName, groupName, {group ->
            if (group != null) {
                val userFirestoreModel = UserFirestoreModel()
                val currentUserId = FirebaseAuth.getInstance().currentUser!!.uid
                userFirestoreModel.setGroup(currentUserId, group, {
                    viewState.finishPicking()
                })


            }
        })

    }
}

在此之前,我尝试在我的activity xml文件中使用Fragment而不是FrameLayout,但是当我在fragmentManager上使用.commit()时,我的应用程序在方向更改时崩溃,并且每次进入时都显示与此处相同的错误它。 但是当我没有打电话给.commit()时,一切都很好。方向改变工作正常(除了重置选定值的事实)并且没有项目加倍。

我以前的活动代码:

class ScheduleActivity : AppCompatActivity(), GroupPickerActivity {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_lessons_list)

        val groupPickerFragment = GroupPickerFragment()

        fragmentManager.beginTransaction()
                .replace(R.id.group_picker_fragment, groupPickerFragment)
    }
} 

1 个答案:

答案 0 :(得分:2)

我的猜测是,当您更改方向时,您要添加两次相同的片段;在你的代码中

fragmentManager.beginTransaction()
        .add(R.id.central_frame, groupPickerFragment)
        .commit()

使用像

这样的替换来更改add方法
fragmentManager.beginTransaction()
        .replace(R.id.central_frame, groupPickerFragment)
        .commit()