Sanjay Kapilesh
Sanjay Kapilesh

Reputation: 399

Cannot access 'RowScopeInstance': it is internal in 'androidx.compose.foundation.layout'

I was trying to achieve the below layout

enter image description here

I tried using Row(Modifier.weight(50f)) that's when the compiler start throwing

If imported from ColumnInstance - import androidx.compose.foundation.layout.ColumnScopeInstance.weight

Cannot access 'ColumnScopeInstance': it is internal in 'androidx.compose.foundation.layout'

If imported from RowInstance - androidx.compose.foundation.layout.RowScopeInstance.weight

Cannot access 'RowScopeInstance': it is internal in 'androidx.compose.foundation.layout'

Attaching my Composable code below

@Composable
fun BoxLayout(){
    Row(Modifier.weight(50f)) {
        BoxWithText()
        BoxWithText()
    }
}

Attaching entire file for reference

package me.sanjaykapilesh.layoutmastery

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScopeInstance.weight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import me.sanjaykapilesh.layoutmastery.ui.theme.LayoutMasteryTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            LayoutMasteryTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    BoxWithText()
                }
            }
        }
    }
}



@Composable
fun BoxLayout(){
    Row(Modifier.weight(50f)) {
        BoxWithText()
        BoxWithText()
    }
}

@Composable
fun BoxWithText() {
    Column() {
        Text(text = "Hello Box!")
        Text(text = "Displays text and follows Material Design guidelines")
    }

}

@Preview(showBackground = true)
@Composable
fun BoxLayoutPreview() {
    LayoutMasteryTheme {
        BoxLayout()
    }
}

I am not sure why I am getting an error. I am also unable to achieve Modifier.weight

Question - https://developer.android.com/codelabs/basic-android-kotlin-compose-composables-practice-problems?authuser=2&continue=https%3A%2F%2Fdeveloper.android.com%2Fcourses%2Fpathways%2Fandroid-basics-compose-unit-1-pathway-3%3Fauthuser%3D2%23codelab-https%3A%2F%2Fdeveloper.android.com%2Fcodelabs%2Fbasic-android-kotlin-compose-composables-practice-problems#3

Upvotes: 21

Views: 27588

Answers (7)

Arghadeep Dey
Arghadeep Dey

Reputation: 53

@Thracian You are right that some methods with Modifier are unique to their scope. e.g. Modifier.weight() only applicable for Column or Row Scope.

Below code is not working--->

Row { //inside Row scope
    Container() 
    Container() 
}
@Composable
container(){
    Column( 
    modifier=Modifier.weight(1f)
) {
    //inside column scope
}

Because it's true that your weight() syntax is right but from where you calling it's wrong. You made a Composable function Container(where your weight is defined) and call it inside Row.

Right syntax is--->

    Row() { //inside Row scope
        Container(modifier=Modifier.weight(1f))
        Container(modifier=Modifier.weight(1f))
    }   
    @Composable
        Container(modifier:Modifier) {
            Column(modifier=modifier) {
                //inside Column scope
            }
        }

In first code weight() inside Column doesn't see any Row /Row Scope although you create it by using custom Composable and inject it inside Row. So, you need to lift the weigth() inside Row/Row Scope.

Upvotes: 3

ExXack
ExXack

Reputation: 51

If other solutions mentioned here does not work and the error Cannot access 'RowScopeInstance': it is internal in 'androidx.compose.foundation.layout' persistently keeps showing,
Then another solution worth trying is removing this line from imports:
import androidx.compose.foundation.layout.RowScopeInstance.weight

This worked for me. Since everything was all right (weight under child of Row/Column) but the error won't go away until I removed that line from imports.

EDIT: Same case for ColumnScopeInstance

Upvotes: 0

Sher Sanginov
Sher Sanginov

Reputation: 595

Inside my composable function, i gave 1f weight to column. This will throw same error because weights only work in children views of parent row or column. That's why it's important to have parent declared as row and column first and then add child views within that parent and then assign weight to each child telling how much space in parent the child should should take.

Column(Modifier.weight(1f)) {
   Text(text="hello")
}

Changed the above code to this, and error is gone:

Row {
        Column(Modifier.weight(.5f)) {

        }
        Column(Modifier.weight(.5f)) {

        }
    }

Upvotes: 0

Dineshraj Srinivasan
Dineshraj Srinivasan

Reputation: 51

weight parameter needs to be called inside any row/column scope. so try this,

 @Composable
    fun BoxLayout(){
       Row{
        Row(Modifier.weight(50f)) {
          BoxWithText()
          BoxWithText()
        }
      }  
    }

Upvotes: 5

Horatio
Horatio

Reputation: 1861

You can use an extension function to get the context. For example:

@Composable
fun ColumnScope.BoxLayout(){
    Row(Modifier.weight(50f)) {
        BoxWithText()
        BoxWithText()
    }
}

Upvotes: 17

Arrahmanul H
Arrahmanul H

Reputation: 19

I've had problems like that too. trouble You can try to block "RowScope" and then press Alt + Enter select "Surround with widget" ended select "Surround with column" solution

Upvotes: 1

Thracian
Thracian

Reputation: 66879

Some modifiers are unique to scopes that they are defined in like Modifier.weight is only available in RowScope or ColumnScope by default. Or Modifier.align is only available inside BoxScope.

When you wish to access these Modifiers you either need to have your Composables functions in these scopes or create a function that takes @Composable argument with Receiver of these scopes

@Composable
fun BoxLayout(){
    Row(Modifier.weight(50f)) {
        BoxWithText()
        BoxWithText()
    }
}

BoxLayout should return RowScope/ColumnScope as this to be able to use Modifier.weight and this can be done as

@Composable
fun BoxWithLayout(content: @Composable RowScope.()->Unit){
    Row {
        content()
    }
}

@Composable
private fun Sample() {
   BoxWithLayout {
       Row(Modifier.weight(50f)) {
           BoxWithText()
           BoxWithText()
       }
   }
}

enter image description here

Upvotes: 23

Related Questions