1

I'm practicing ViewPager in JetPack compose which is experimental right now.

I was able to successfully make a basic view pager, but when trying to add an indicator, I get an error: Cannot access 'ColumnScopeInstance': it is internal in 'androidx.compose.foundation.layout'

Indicator code; (please keep in keep I already imported it) enter image description here

I tried looking for answers, I found a similar problem problem here on stackOverFlow, but I don't understand.

I also found out that I could only use horizontalAlignment = Alignment.CenterHorizontally in a column.

To ask bluntly, How do I position ViewPager Indicator Center Horizontally.

And I followed the procedure on the official document for pager indicator, I don't know what I'm missing.

I'm highly open to Ideas. Thanks to you in Advance. \If you details is needed I'm more than happy to provide.

Edwin
  • 565
  • 11
  • 26

2 Answers2

4

alignment and arrangement depend on the parent's view. for example if you're using 'HorizontalPagerIndicator' inside of a box, you can use:

Box(contentAlignment = Alignment.Center) {....}

otherwise, if your parent view is Column, I suggest doing it this way:

 Column(
        modifier = ....,
        horizontalAlignment = Alignment.CenterHorizontally
 ) {...}

or for Row:

Row( 
    modifier = ....,
    horizontalArrangement = Arrangement.Center
) {...}
Mohammad Derakhshan
  • 1,262
  • 11
  • 33
2

You can put your ViewPager and HorizontalPagerIndicator inside a box with contentAlignment = Alignment.Center/TopCenter/BottomCenter.

@Composable
private fun AlignmentSample() {
    Box(contentAlignment = Alignment.Center) {
        HorizontalPager(()
        HorizontalPagerIndicator()
    }
}

What i mean in the answer in the link you shared is some modifiers are unique to scopes of some Composables. For instance Modifier.align() is available is only inside Box. because of that you either need to place your content inside Box or you need to set a receiver to your @Composable argument such as

@Composable
private fun BoxScopeSample(
    modifier: Modifier = Modifier,
    content: @Composable BoxScope.() -> Unit
) {
    // You can't call content() here because it has BoxScope receiver
    Box(modifier) { // this here is BoxScope
        content()
    }
}

inside content lambda you can call Modifier.align() which is unique to BoxScope and use it as

BoxScopeSample(modifier = Modifier.size(200.dp).border(2.dp, Color.Cyan)) {
    Row(
        Modifier
            .align(Alignment.TopStart)
            .background(Color.Red)
            .size(100.dp)
    ) {

    }

    Row(
        Modifier
            .align(Alignment.BottomEnd)
            .background(Color.Green)
            .size(100.dp)
    ) {

    }
}

Which will look as

enter image description here

Then create another Composable with no scope such as

@Composable
private fun NonScopeSample(
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit
) {

    Box(modifier) {
        content()
    }
}

And try calling

NonScopeSample(modifier = Modifier
    .size(200.dp)
    .border(2.dp, Color.Cyan)) {
    Row(
        Modifier
            .align(Alignment.TopStart)
            .background(Color.Red)
            .size(100.dp)
    ) {

    }

    Row(
        Modifier
            .align(Alignment.BottomEnd)
            .background(Color.Green)
            .size(100.dp)
    ) {

    }
}

you will get compile error because Modifier.align is not a generic Modifier as i mentioned above.

Thracian
  • 43,021
  • 16
  • 133
  • 222
  • I'm sinerely grateful for your time. Please I don't quite understand your explanation. – Edwin Nov 09 '22 at 00:46
  • @Edwin you have you tried out the snippets i posted? In most simple terms some modifiers are unique to some Composables so you need to make sure either your content composable inside one of these composaables like Box, Row, Column or need to have some attachment(Receiver) to that Composable to be able use these unique modifiers – Thracian Nov 09 '22 at 05:06
  • Answer is only the `AlignmentSample`, rest is explanation of the answer you shared as link. You need to check out Row, Column, Box and Modifier.weight and Modifier.align to see when you can use these modifiers – Thracian Nov 09 '22 at 05:08
  • Thanks again for your help. Yes, I tried the snippets you posted. The AlignmentSample, to be specific, but doing it like that doesn't center the indicator it center everything.. And Because the ViewPager composable is part of a larger composable it doesn't look good. I've mohammed's suggestion, I put a column inside the Indicator function and gave it a center alignment, and this fixes it... I sincerely thank you for your effort and time thracian. – Edwin Nov 09 '22 at 15:47