I'm writing an Android app in Android Studio with Kotlin. As I'm new to this, I had a wrong perception that every new 'shot' needs a new activity. I'm writing a story game with multiple shots.
So, my activities differ only by data.
There 2 types of repeating parts:
1st: only picture on the screen is changing with next-button press.
Code:
class Kadr1Activity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_kadr01)
}
fun nextClick(view: View) {
val intentKadr2 = Intent(this, Kadr2Activity::class.java) //every next button intents next shot
startActivity(intentKadr2)
this.finish()
}
fun backClick(view: View){
val intentKadr0 = Intent(this, MainActivity::class.java) //every back button intents previous shot
startActivity(intentKadr0)
this.finish()
}
}
2nd: user should solve the task by clicking the correct answer.
Code:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_kadr13)
}
var flag = false
fun nextClick(view: View) {
val intentKadr14 = Intent(this, Kadr14Activity::class.java)
startActivity(intentKadr14)
this.finish()
}
fun backClick(view: View){
val intentKadr12 = Intent(this, Kadr12Activity::class.java)
startActivity(intentKadr12)
this.finish()
}
fun btn1Click(view: View){
ans131Btn.setImageResource(R.drawable.btn_13_1_chosen) //picture of chosen button is changed every time it is pressed
ans132Btn.setImageResource(R.drawable.btn_13_2)
ans133Btn.setImageResource(R.drawable.btn_13_3)
flag = false
}
fun btn2Click(view: View){
ans132Btn.setImageResource(R.drawable.btn_13_2_chosen)
ans131Btn.setImageResource(R.drawable.btn_13_1)
ans133Btn.setImageResource(R.drawable.btn_13_3)
flag = true
}
fun btn3Click(view: View){
ans133Btn.setImageResource(R.drawable.btn_13_3_chosen)
ans131Btn.setImageResource(R.drawable.btn_13_1)
ans132Btn.setImageResource(R.drawable.btn_13_2)
flag = false
}
}
I've read that it would be better to get rid of repeating parts of code and refactor it somehow.
Could anyone give me a hint where I can actually find how to refactor my code? Would be very grateful.
Related
I'm trying to implement a first time using screen (like any other app when you have to fill some options before using the app for the first time).
I can't go to another Jetpack compose on an main activity on-create state because it check that every recomposition, and take me to the navigation path (I'd like to check the datastore entry once during launch), this what I already try, not seem to be working:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycleScope.launch {
val onBoardingStatus = dataStoreManager.onBoard.first()
setContent {
val navController = rememberNavController()
OnBoardingNavHost(navController)
navController.navigate(if (onBoardingStatus) "on_boarding" else "main") {
launchSingleTop = true
popUpTo(0)
}
}
}
}
it is possible to check that only once (in application class for example and not in oncreate?)
please advice,
thanks in advance
You have to use LaunchedEffect for this, you can do something like this
enum class OnboardState {
Loading,
NoOnboarded,
Onboarded,
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
var onboardingState by remember {
mutableStateOf(OnboardState.Loading)
}
LaunchedEffect(Unit) {
onboardingState = getOnboardingState()
}
when (onboardingState) {
OnboardState.Loading -> showSpinner()
OnboardState.NoOnboarded -> LaunchedEffect(onboardingState) {
navigateToOnboarding()
}
OnboardState.Onboarded -> showContent()
}
}
}
I want that when the user has installed the application, he can accept the terms and conditions by clicking on the accept button. But this should only happen once when the user first starts the application. I use kotlin
I try this, but not work
class tutorial: AppCompatActivity() {
private var pref: SharedPreferences = getSharedPreferences("mypref", MODE_PRIVATE)
override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
super.onCreate(savedInstanceState, persistentState)
setContentView(R.layout.tutorial_main)
if (pref.getBoolean("firstTime", false)) {
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}
}
}
You are defaulting to false when the preference value has never been set, so it will always be false. You want it to be considered true when the app is opened the first time.
You are failing to ever change the value of the preference, so even after you fix the default to be true, it will never change to false.
You should show your terms and conditions when it's the first time, and directly open the main activity when it's not the first time. You have the logic flipped.
You need to set a default of true, and you need to persist a value of false:
class tutorial: AppCompatActivity() {
private var pref: SharedPreferences = getSharedPreferences("mypref", MODE_PRIVATE)
override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
super.onCreate(savedInstanceState, persistentState)
setContentView(R.layout.tutorial_main)
if (pref.getBoolean("firstTime", true)) { // use default of true
pref.edit { putBoolean("firstTime", false) } // persist value of false
// show T&C dialog that calls goToMain() when accepted
} else {
goToMain()
}
}
private fun goToMain() {
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
finish() // close this activity since we don't want it in back stack
}
}
By the way, class names by convention should always begin with a capital letter. It will make your code easier to read and understand.
I haven't found anything over the past day that shows how to do this action, everything I've seen is with a basic button of which I am unable to replicate for use with an image button. using setOnClickListener does not seem to work at all though the only cases I found of using them were 5+ years old.
Is there a Storyboard equivalent of linking activities in Android Studio?
Here is an example I found but 7 years old.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val myButton =
findViewById<View>(R.id.live) as ImageButton
myButton.setOnClickListener(object : OnClickListener() {
// When the button is pressed/clicked, it will run the code below
fun onClick() {
// Intent is what you use to start another activity
val intent = Intent(this, LiveActivity::class.java)
startActivity(intent)
}
})
}
}
gives the following error:
Object is not abstract and does not implement abstract member public abstract fun onClick(p0: View!): Unit defined in android.view.View.OnClickListener
The problem is that you haven't included the View parameter to your onClick override. The signature of OnClickListener.onClick includes a View (the View that was clicked) as its parameter, so onClick() (with no parameters) doesn't match that signature.
You could either add it explicitly (in which case you also need to refer to the Activity's this explicitly with ActivityName.this, as this refers to the OnClickListener otherwise):
myButton.setOnClickListener(object : View.OnClickListener {
// When the button is pressed/clicked, it will run the code below
override fun onClick(view: View) {
// Replace ActivityName with the name of your Activity that this is in
val intent = Intent(ActivityName.this, LiveActivity::class.java)
startActivity(intent)
}
})
or use Kotlin's SAM conversions to add it implicitly (I'd do this approach):
// When the button is pressed/clicked, it will run the code below
myButton.setOnClickListener { // there's an implicit view parameter as "it"
// Intent is what you use to start another activity
val intent = Intent(this, LiveActivity::class.java)
startActivity(intent)
}
Fix
Change from:
myButton.setOnClickListener(object : OnClickListener { })
to
myButton.setOnClickListener(object : View.OnClickListener { })
so method will be:
override fun onClick(v: View?) {
// Do something
}
instead yours:
fun onClick() {
}
Full code:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val myButton = findViewById<ImageButton>(R.id.live)
myButton.setOnClickListener(object : View.OnClickListener {
// When the button is pressed/clicked, it will run the code below
override fun onClick(v: View?) {
// Intent is what you use to start another activity
val intent = Intent(this, LiveActivity::class.java)
startActivity(intent)
}
})
}
}
I am a beginner in Android. I have two layout resource files as shown above.
I want to type a word in the first one and click the button, then it is suppose to go to the 2nd layout resource file and display the word on the text view box. I keep getting an error whenever I try.
Below is the code I wrote
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
button.setOnClickListener {
startActivity(Intent(this, NewLayoutActivity::class.java))
}
}
for the new layout activity
class NewLayoutActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.new_layout)
textView.text = ${editText.text}
}
you should try `intent
var data2 = editText.text.toString
val intent = Intent(applicationContext,secondActivity::class.java)
intent.putExtra("name",data2)
startActivity(intent)
in the second
val data = intent.getStringExtra("name")
you should learn navigation its better and easier
pass data with intent while open new activity:
val intent = Intent(this, NewLayoutActivity::class.java)
intent.putExtra("value", "value you want to pass")
startActivity(intent)
And get in second activity as:
var bundle :Bundle ?=intent.extras
var message = bundle!!.getString("value") // if the value is type of String
change your code from this
button.setOnClickListener {
startActivity(Intent(this, NewLayoutActivity::class.java))
}
to this
val value = edit_text_id.text
button.setOnClickListener {
startActivity(Intent(this, NewLayoutActivity::class.java)
.putExtra("key", value))
}
then, get your value on second activity with this
val value = Intent().getStringExtra("key")
text_view_id.text = value
On one page, I have a memory game level and I created a menu so once a button has been pressed it will take you to that page. The problem is each time I press the button my app crashes.
class Main2Activity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
buttonEasy.setOnClickListener{
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}
}
}
First You Need To Intialized Your Button (buttonEasy)
buttonEasy = findViewById(R.id.buttonEasy);
Write OnClick Method For Both Types :
buttonEasy.setOnClickListener(object: View.OnClickListener {
override fun onClick(view: View): Unit {
val intent = Intent(context, MainActivity::class.java);
startActivity(intent);
}
})
Or you can write as
buttonEasy.setOnClickListener {
val intent = Intent(context, MainActivity::class.java)
startActivity(intent);
}
After then you getting still errors & crashing your app, check your MainActivity Code and verify your xml file.