[FIXED] How to use Android Material Stepper library for form validation in old Android Project but the UI is need to create by using Jetpack compose

Issue

  1. I merged my old Android Kotlin project with jetpack compose.
  2. I have tried different methods for using stepper library but it wont work.
  3. I have also try adding this in my xml but it wont work. can anyone help.
  4. and created a adapter for stepper also but it wont work
<androidx.compose.ui.platform.ComposeView
        android:id="@+id/compose_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

  <com.stepstone.stepper.StepperLayout
            android:id="@+id/stepperLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="?actionBarSize"
            app:ms_backButtonColor="@color/app_primary_accent"
            app:ms_completeButtonColor="@color/app_primary_accent"
            app:ms_completeButtonText="Submit"
            app:ms_nextButtonColor="@color/app_primary_accent"
            app:ms_stepperType="dots" />

Solution

  1. i have created it using the fragments.
    Add this in your your activity where you want to add stepper.
    (test_activity.xml)

<com.stepstone.stepper.StepperLayout
            android:id="@+id/stepperLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="?actionBarSize"
            app:ms_backButtonColor="@color/app_primary_accent"
            app:ms_completeButtonColor="@color/app_primary_accent"
            app:ms_completeButtonText="Submit"
            app:ms_nextButtonColor="@color/app_primary_accent"
            app:ms_stepperType="dots" />
  1. add below lines in your activity TestActivity.kt
class TestActivity : AppCompatActivity(), StepperLayout.StepperListener {
    private lateinit var stepperLayout: StepperLayout

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
        setContentView(R.layout.test_activity)

        stepperLayout = findViewById(R.id.stepperLayout)
        stepperLayout.adapter = StepperAdapter(supportFragmentManager, this)
        stepperLayout.setListener(this)
        actionBarToolbar?.post { supportActionBar?.subtitle = "Page 1" }// custom action bar
    }
    override fun onCompleted(completeButton: View?) {
       var intent= Intent(this,TestActivity::class.java)
        startActivity(intent)
        finish()
    }
    override fun onError(verificationError: VerificationError?) {
    }
    override fun onStepSelected(newStepPosition: Int) {
        val subTitle = when (newStepPosition) {
            0 -> "Page 1"
            1 -> "Page 2"
            2 -> "Page 3"
            else -> ""
        }
        supportActionBar?.subtitle = subTitle
    }
    override fun onReturn() {
        finish()
    }
}
  1. create a adapter for stepper
class StepperAdapter(fm: FragmentManager?, context: Context?) :
    AbstractFragmentStepAdapter(fm!!, context!!) {

    override fun getCount(): Int {
        return 8
    }

    override fun createStep(position: Int): Step {
        return when (position) {
            0 -> Page1.newInstance()
            1 -> Page2.newInstance()
            2 -> Page3.newInstance()
            else -> throw IllegalArgumentException("Unsupported position: $position")
        }
    }
}

  1. create fragments for each page
class Page1 : Fragment(), Step {
    companion object {
        fun newInstance() = Page1()
    }
    @ExperimentalComposeUiApi
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return ComposeView(requireContext()).apply {
            setContent {
                JFLtestTheme {
                    Page1JetCompose()
                }
            }
        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    }
    override fun verifyStep(): VerificationError? {
        val message = validateInitData()
        return null
    }
    override fun onSelected() {}
    override fun onError(error: VerificationError) {
        ShowDialog.showSnackbar(view, error.errorMessage)
    }
}
  1. now create jetcompose file and add your layout
@Composable
fun Page1Jetcompose() {
    val context = LocalContext.current
    val emailState = remember { mutableStateOf("") }
    val focusRequester = remember { FocusRequester() }
    val focusManager = LocalFocusManager.current

    Column {
        TextField(
            modifier = Modifier
                .focusRequester(focusRequester)
                .fillMaxWidth(),
            value = emailState.value,
            onValueChange = {
                emailState.value = it
            },
        )
        Button(onClick = {
            focusManager.clearFocus()
            if (emailState.value.isEmpty() ) {
                focusRequester.requestFocus()
                Toast.makeText(context, "error", Toast.LENGTH_SHORT).show()
            }
        }) { Text(text = "Button")
        }
    }
}

Answered By – Uzumaki

Answer Checked By – Mary Flores (Easybugfix Volunteer)

Leave a Reply

(*) Required, Your email will not be published