如何在旧的 Android 项目中使用 Android Material Stepper 库进行表单验证,但需要使用 Jetpack compose 创建 UI

发布于 2025-01-10 22:24:55 字数 894 浏览 0 评论 0原文

  1. 我将旧的 Android Kotlin 项目与 jetpack compose 合并。
  2. 我尝试了不同的方法来使用步进器库,但它不起作用。
  3. 我也尝试将其添加到我的 xml 中,但它不起作用。谁能帮忙。
  4. 并为步进器创建了一个适配器,但它不起作用
<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" />

  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" />

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无法言说的痛 2025-01-17 22:24:55
  1. 我已经使用片段创建了它。
    将其添加到您要添加步进器的活动中。
    (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. 在您的活动 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. 步进器创建适配器
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. 为每个页面创建片段
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. 现在创建 jetcompose 文件并添加您的布局
@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")
        }
    }
}
  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")
        }
    }
}
奈何桥上唱咆哮 2025-01-17 22:24:55

因为我希望视图完全使用 Jetpack Compose 编写,所以我创建了一个 Material Stepper 库。

  1. build.gradle 中添加 jitpack
allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}
  1. 添加 Material Stepper Compose 库到您的 app/build.gradle
dependencies {
     ...
     implementation "com.github.Xsims:compose-material-stepper:0.2.0"
}
  1. 创建一个 Stepper,其中包含 Step一个可组合的函数,
@Composable
fun MyStepper() {
    Stepper(
        steps = List(8) { index ->
            Step(
                title = "Name of step ${index + 1}",
                subtitle = "Subtitle of step ${index + 1}"
            ) {
                Box(
                    modifier = Modifier
                        .height(250.dp)
                        .fillMaxWidth()
                        .background(color = Color.Black)
                )
            }
        }
    )
}

  1. 您可以自定义管理状态的步骤
val state = mutableStateOf(StepState.TODO)
lateinit var currentStep: MutableState<Int>

val steps = listOf(Step(
    title = "My state Step",
    state = state,
) {
    when (state.value) {
        StepState.TODO -> Button(onClick = {
            state.value = LOADING
            CoroutineScope(Dispatchers.IO).launch { delay(2000) }
                .invokeOnCompletion { state.value = ERROR }
        }) {
            Text("CLICK")
        }

        LOADING -> CircularProgressIndicator()

        ERROR -> Button(onClick = {
            state.value = COMPLETE
            nextStep()
        }) {
            Text("RETRY")
        }

        COMPLETE -> Text("Complete")
    }
}, Step(title = "My second step") {
    Text("Second step")
}, Step(title = "My third step") {
    Text("Third step")
},
)

fun nextStep() {
    if (currentStep.value < steps.size)
        currentStep.value = currentStep.value + 1
}

@Composable
fun MyStepper() {
    currentStep = remember { mutableStateOf(0) }
    Stepper(
        currentStep = currentStep,
        steps = steps
    )
}

不同状态的材质步进库演示

Because I wanted the view to be written entirely with Jetpack Compose, I made a Material Stepper library.

  1. Add jitpack in your build.gradle
allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}
  1. Add Material Stepper Compose library to your app/build.gradle
dependencies {
     ...
     implementation "com.github.Xsims:compose-material-stepper:0.2.0"
}
  1. Create a Stepper with Steps in a composable function
@Composable
fun MyStepper() {
    Stepper(
        steps = List(8) { index ->
            Step(
                title = "Name of step ${index + 1}",
                subtitle = "Subtitle of step ${index + 1}"
            ) {
                Box(
                    modifier = Modifier
                        .height(250.dp)
                        .fillMaxWidth()
                        .background(color = Color.Black)
                )
            }
        }
    )
}

  1. You can customize Step to manage state
val state = mutableStateOf(StepState.TODO)
lateinit var currentStep: MutableState<Int>

val steps = listOf(Step(
    title = "My state Step",
    state = state,
) {
    when (state.value) {
        StepState.TODO -> Button(onClick = {
            state.value = LOADING
            CoroutineScope(Dispatchers.IO).launch { delay(2000) }
                .invokeOnCompletion { state.value = ERROR }
        }) {
            Text("CLICK")
        }

        LOADING -> CircularProgressIndicator()

        ERROR -> Button(onClick = {
            state.value = COMPLETE
            nextStep()
        }) {
            Text("RETRY")
        }

        COMPLETE -> Text("Complete")
    }
}, Step(title = "My second step") {
    Text("Second step")
}, Step(title = "My third step") {
    Text("Third step")
},
)

fun nextStep() {
    if (currentStep.value < steps.size)
        currentStep.value = currentStep.value + 1
}

@Composable
fun MyStepper() {
    currentStep = remember { mutableStateOf(0) }
    Stepper(
        currentStep = currentStep,
        steps = steps
    )
}

demo of material stepper library with different state

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文