So i was trying to get some text modifier with padding and it was all going good until I imported androidx.compose.foundation.layout.padding and the error on Modifier.padding(10.dp) didnt disapear, i tried searching if the import is moved/deprecated but i didnt see any changed releated to it. It also tells me the import isnt used so im really confused.
I use:
Android Studio - Arctic Fox 2020.3.1 canary 1
Kotlin Plugin - 1.4.10-Studio4.2-1\
My full code:
package com.example.weather
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.Text
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.setContent
import androidx.compose.ui.unit.dp
import androidx.ui.tooling.preview.Preview
import com.example.weather.ui.ExampleWeatherTheme
import java.lang.reflect.Modifier
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ExampleWeatherTheme {
Surface(color = MaterialTheme.colors.background) {
Column(modifier = Modifier.padding(10.dp)) {
FeelsLike(50)
}
}
}
}
}
}
#Composable
fun FeelsLike(feelstemp: Int) {
Text(text = "Feels Like: $feelstempĀ°")
}
#Composable
fun Temperature(temp: Int) {
Text(text = "$temp")
}
#Preview(showBackground = true)
#Composable
fun BasicPreview() {
ExampleWeatherTheme(darkTheme = true) {
FeelsLike(50)
}
}
This is your issue:
import java.lang.reflect.Modifier
You are importing the wrong Modifier class. It happened to me and the error can be quite missleading. Change the import to:
import androidx.compose.ui.Modifier
Related
I am trying to run a test using Espresso in jetpack compose. Everytime I run it, it gives this error.
androidx.test.espresso.NoMatchingViewException: No views in hierarchy found matching: an instance of android.widget.TextView and view.getText() with or without transformation to match: is "Count"
My MainActivity.kt
package com.example.testing
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.testing.ui.theme.TestingTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
TestingTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
Greeting()
}
}
}
}
}
#Composable
fun Greeting() {
var counter by remember{
mutableStateOf(0)
}
Column(
modifier = Modifier
.fillMaxSize()
.wrapContentSize(Alignment.Center)
) {
Text(text = stringResource(id = R.string.Count),
modifier = Modifier
.padding(8.dp)
.testTag(stringResource(id = R.string.)))
Button(onClick = { counter++ }) {
Text(text = stringResource(id = R.string.Increment))
}
}
}
#Preview(showBackground = true)
#Composable
fun DefaultPreview() {
TestingTheme {
Greeting()
}
}
My test.kt
package com.example.testing
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import com.microsoft.appcenter.espresso.ReportHelper;
import androidx.lifecycle.Lifecycle
import androidx.test.core.app.ActivityScenario
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.*
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import com.microsoft.appcenter.espresso.Factory
import org.junit.After
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
import org.junit.Before
import org.junit.Rule
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
#RunWith(AndroidJUnit4::class)
#LargeTest
class ExampleInstrumentedTest {
#Rule
val activityRule = ActivityScenarioRule(MainActivity::class.java) //espresso
#Test
fun testClick() {
onView(withText("Count")).check(matches(isDisplayed()))
}
}
I have Count in string.xml as Count. I have emulator up and running fine. It seems like it is not able to detect the Activity.
In #Test, if I skip
.check(matches(isDisplayed()))
part from
onView(withText("Count")).check(matches(isDisplayed()))
it passes.
Also I have tried junit4
val composeTestRule = createAndroidComposeRule<MainActivity>()
And it works but espresso isn't working
You can use:
#get:Rule
val composeRule = createComposeRule()
#Test
fun testClick() {
composeRule.setContent {
TestingTheme {
Greeting()
}
}
composeRule.onNodeWithText("Count").assertIsDisplayed()
}
As alternative you can also use:
#OptIn(ExperimentalFoundationApi::class, ExperimentalComposeUiApi::class)
#get:Rule
val composeTestRule = createAndroidComposeRule<MainActivity>()
#OptIn(ExperimentalFoundationApi::class, ExperimentalComposeUiApi::class)
#Test
fun testClick() {
composeTestRule.onNodeWithText("Count").assertIsDisplayed()
}
I was trying to achieve the below layout
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
You can use an extension function to get the context. For example:
#Composable
fun ColumnScope.BoxLayout(){
Row(Modifier.weight(50f)) {
BoxWithText()
BoxWithText()
}
}
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()
}
}
}
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
I am in need of a datepicker in jetpack compose. Though to use the ordinary Datepicker in jetpack compose you need to parse Mainactivity to A AppcompatActivity. Though to do that what i understand the Mainactivity needs to extend AppCompatActivity? i am not able to get this to work can anyone please tell me what im doing wrong. I have already tried to extend AppCompatActivity as i said but then it gives you an error because it has to extend ComponentActivity? if i use this answer: AppCompatActivity instead of ComponentActivity in Jetpack compose i get this error.
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.jens.svensson.paper_seller/com.jens.svensson.paper_seller.MainActivity}: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
Main Activity
package com.jens.svensson.paper_seller
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.material.rememberScaffoldState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import com.google.android.material.datepicker.MaterialDatePicker
import com.jens.svensson.paper_seller.core.navigation.Navigation
import com.jens.svensson.paper_seller.core.navigation.Screens
import com.jens.svensson.paper_seller.core.presentation.components.StandardScaffold
import com.jens.svensson.paper_seller.ui.theme.PaperSellerTheme
import dagger.hilt.android.AndroidEntryPoint
#AndroidEntryPoint
#ExperimentalComposeUiApi
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
PaperSellerTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
val navController = rememberNavController()
val navBackStackEntry by navController.currentBackStackEntryAsState()
val scaffoldState = rememberScaffoldState()
StandardScaffold(
modifier = Modifier.fillMaxSize(),
navController = navController,
navBackStackEntry = navBackStackEntry,
showBottomBar = navBackStackEntry?.destination?.route in listOf(
Screens.CustomerListScreen.route,
Screens.CalculationScreen.route,
Screens.ChatScreen.route,
Screens.SettingsScreen.route
),
showFloatButton = navBackStackEntry?.destination?.route in listOf(
Screens.CustomerListScreen.route
),
state = scaffoldState,
onFabClick = {navController.navigate(Screens.AddEditCustomerScreen.route)}
) {
Navigation(navController, scaffoldState)
}
}
}
}
}
}
#Preview(showBackground = true)
#Composable
fun DefaultPreview() {
PaperSellerTheme {
}
}
The datebuttonForm
package com.jens.svensson.paper_seller.feature_customer.presentation.components
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.DateRange
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.core.util.Pair
import com.google.android.material.datepicker.MaterialDatePicker
import com.jens.svensson.paper_seller.core.util.Constants
#Composable
fun ChosenDateForm(datePicked: String?, updatedDate: (Pair<Long, Long>) -> Unit){
val activity = LocalContext.current as AppCompatActivity
Box(modifier = Modifier.clickable { showDatePicker(activity = activity, updatedDate = updatedDate)}
.padding(Constants.STANDARD_TEXTFIELD_PADDING.dp, top = 10.dp)
.background(MaterialTheme.colors.secondaryVariant, RoundedCornerShape(20))
.fillMaxWidth()
.border(width = 1.dp, color = MaterialTheme.colors.primary, RoundedCornerShape(20))){
Row(modifier = Modifier
.padding(16.dp)
.fillMaxWidth()) {
Text(modifier = Modifier.weight(1f), text = "Today", style = MaterialTheme.typography.body1)
Icon(Icons.Default.DateRange, contentDescription = "Select Date")
}
}
}
private fun showDatePicker(activity: AppCompatActivity, updatedDate: (Pair<Long, Long>) -> Unit){
val calendar = MaterialDatePicker.Builder.dateRangePicker().build()
calendar.show(activity.supportFragmentManager, calendar.toString())
calendar.addOnPositiveButtonClickListener {
updatedDate(it)
}
}
I'm having an issue where I've imported an import in order for a piece of code to work but no matter how many times I import the import, the code isn't recognizing that it's there. I've already tried invalidating and restarting, multiple times. I've read that another solution to this is to Sync with File System, but I don't appear to have that option under File.
The import in question is import java.text.MessageFormat.format
import android.content.ContentValues.TAG
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import com.squareup.okhttp.internal.http.HttpDate.format
import java.math.BigDecimal
import java.sql.Time
import java.sql.Timestamp
import java.text.DateFormat
import java.text.MessageFormat.format
import java.util.*
import kotlin.collections.ArrayList
class RemindersActivity : AppCompatActivity() {
lateinit var petID: String
val db = Firebase.firestore
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_reminders)
displayReminders()
petID = intent.getStringExtra("petID").toString()
val fab: View = findViewById(R.id.fab_reminders)
fab.setOnClickListener {
val intent = Intent(this, AddReminderActivity::class.java)
intent.putExtra("petID", petID)
startActivity(intent)
}
}
override fun onStart() {
super.onStart()
displayReminders()
}
private fun displayReminders() {
val recyclerview = findViewById<RecyclerView>(R.id.recyclerview_reminders)
recyclerview.layoutManager = LinearLayoutManager(this)
db.collection("pets").document(petID).collection("reminders").get().addOnSuccessListener { result ->
val data = mutableListOf<RemindersData>()
for (document in result) {
val title = document.data["title"].toString()
val timestamp = document.data["timestamp"] as Long
val cal = Calendar.getInstance()
cal.timeInMillis = timestamp * 1000L
val date = DateFormat.format("dd-MM-yyyy hh:mm:ss aa", cal).toString() //<- code note recognizing import is format
val frequency = document.data["frequency"].toString()
data.add(RemindersData(title, date, frequency))
}
val adapter = RemindersAdapter(data)
recyclerview.adapter = adapter
}.addOnFailureListener { e->
Log.w(TAG, "Error getting documents", e)
}
}
}
It just seems that you have added a few imports from the java packages instead of the android packages. It can happen when you use auto import in the IDE and there are multiple options and you click the wrong one.
When that happens you either have to undo the import or fix it manually.
Remove the import for
import java.text.DateFormat
Add the import for
import android.text.format.DateFormat
Afterwards, if there are any unused imports left, you can remove those as well.
i'm practising a bit with kotlin and was testing Room and livedata, my app gets data from a json and the stores it in room, i want to move this network call to its own file and class, but if i do so the observer i set to get the changes don't trigger anymore, any help would be appreciated
here is a snipped of my mainactivity, if more is needed to know what happens please let me know
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
import android.widget.Toast
import androidx.activity.viewModels
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.viewModelScope
import androidx.room.Room
import com.optiva.videoplayer.data.*
import com.optiva.videoplayer.network.GetData
import com.optiva.videoplayer.network.Networking
import com.optiva.videoplayer.network.RetrofitConnect
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val dbcategories = Room.databaseBuilder(applicationContext, CategoriesDatabase::class.java,"categories.db").build()
val dbvideo = Room.databaseBuilder(applicationContext, VideosDatabase::class.java,"videos.db").build()
val retrofitData = RetrofitConnect.retrofitInst?.create(GetData::class.java)
val categoriesList = retrofitData?.getAll()
categoriesList?.enqueue(object: Callback<DataList> {
override fun onResponse(
call: Call<DataList>,
response: Response<DataList>
) {
val test = response?.body()
val cat = test?.categories
val vid = test?.videos
lifecycleScope.launch(Dispatchers.IO) {
if (cat != null) {
for(c in cat){
dbcategories.categoriesDAO().insertAll(CategoriesEntity(c.id,c.title,c.type))
}
}
if (vid != null) {
for(v in vid){
dbvideo.VideosDAO().insertAll(VideosEntity(v.id,v.thumb,v.videoUrl,v.categoryId,v.name))
}
}
}
}
override fun onFailure(call: Call<DataList>, t: Throwable) {
Toast.makeText(applicationContext,"error", Toast.LENGTH_LONG).show()
}
})
val textView: TextView = findViewById(R.id.test) as TextView
dbcategories.categoriesDAO().getALL().observeForever({categories ->
if(categories.size>0){
textView.text= categories[0].title
}
})
dbcategories.categoriesDAO().getALL().observe(this, {categories ->
if(categories.size>0){
textView.text= categories[0].title
}
}
} ```