Following tutorial to change set view based on button click.
When I set the variable in onCreate, somehow, I cannot refer to them in functions.
abstract class MainActivity : AppCompatActivity() {
var count = 0
fun reset(view: View) {
count = 0
textView.setText(count.toString())
}
fun plusOne(view: View) {
count++
textView.setText(count.toString())
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var textView = findViewById<TextView>(R.id.textView)
textView.text = "Hello Fam"
}
}
Try with the following code.
abstract class MainActivity : AppCompatActivity() {
private lateinit var textView:TextView
var count = 0
fun reset(view: View) {
count = 0
textView.setText(count.toString())
}
fun plusOne(view: View) {
count++
textView.setText(count.toString())
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
textView = findViewById<TextView>(R.id.textView)
textView.text = "Hello Fam"
}
}
Related
class suspect : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_suspect)
imagebutton.setOnClickListener {
imagebutton.setImageResource(R.drawable.picture2)
}
}
}
You could save an image identifier to Shared Preferences and then retrieve an image number from Shared Preferences when you open your activity. Then you use that number to set the ImageButton image.
I haven't ran this code, but something along the lines of this should work:
private val picture1Id = 1
private val picture2Id = 2
private val IMAGE_KEY = "IMAGE_KEY"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_suspect)
imagebutton.setOnClickListener {
saveImageIdentifier(picture2Id)
imagebutton.setImageResource(R.drawable.picture2)
}
setupImageButtonFromPreferences()
}
private fun saveImageIdentifier(id: Int) {
val sharedPref = activity?.getPreferences(Context.MODE_PRIVATE) ?: return
with (sharedPref.edit()) {
putInt(IMAGE_KEY, id)
apply()
}
}
private fun getImageIdentifier(): Int {
val sharedPref = activity?.getPreferences(Context.MODE_PRIVATE) ?: return 1
return sharedPref.getInt(IMAGE_KEY, 1)
}
private fun setupImageButtonFromPreferences() {
when (getImageIdentifier()) {
picture1Id -> imagebutton.setImageResource(R.drawable.picture1)
picture2Id -> imagebutton.setImageResource(R.drawable.picture2)
else -> return
}
}
var a = 0
class suspect : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_suspect)
if (a == 1){imagebutton.setImageResource(R.drawable.picture2)}
imagebutton.setOnClickListener {
imagebutton.setImageResource(R.drawable.picture2)
a = 1
}
imagebutton.setOnLongClickListener {
imagebutton.setImageResource(R.drawable.picture1)
a = 0
true
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putInt("image", a)
}
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
a = savedInstanceState.getInt("image")
}
}
I'm learning Kotlin from Java, and I'm trying to figure out how to create and store the ViewModel. Storing it outside the main activity will cause it to crash, but storing it inside the main activity means my private variables cannot access them, so I get an error.
Here's the code I have
class MainActivity : AppCompatActivity() {
private lateinit var trueButton: Button
private lateinit var falseButton: Button
private lateinit var nextButton: Button
private lateinit var prevButton: Button
private lateinit var questionTextView: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val quizViewModel: QuizViewModel = ViewModelProvider(this).get(QuizViewModel::class.java)
trueButton = findViewById(R.id.true_button)
falseButton = findViewById(R.id.false_button)
nextButton = findViewById(R.id.next_button)
prevButton = findViewById(R.id.back_button)
questionTextView = findViewById(R.id.question_text)
trueButton.setOnClickListener {
checkAnswer(true)
}
falseButton.setOnClickListener {
checkAnswer(false)
}
nextButton.setOnClickListener {
quizViewModel.moveToNext()
updateQuestion()
}
prevButton.setOnClickListener {
quizViewModel.moveToBack()
updateQuestion()
}
updateQuestion()
}
private fun checkAnswer(userAnswer: Boolean){
val correctAnswer = quizViewModel.currentQuestionAnswer
val messageResId = if (userAnswer == correctAnswer) {
R.string.correct_toast
} else {
R.string.incorrect_toast
}
Toast.makeText(
this,
messageResId,
Toast.LENGTH_SHORT
).show()
}
private fun updateQuestion() {
val questionTextResID = quizViewModel.currentQuestionText
questionTextView.setText(questionTextResID)
}
}
Unfortunately, putting the ViewModel inside my onCreate means I can't access them in my functions, namely checkAnswer and updateQuestion.
import androidx.lifecycle.ViewModel
class QuizViewModel : ViewModel() {
private val questionBank = listOf(
Question(R.string.question_aus, true),
Question(R.string.question_ocean, true),
Question(R.string.question_mideast, false),
Question(R.string.question_africa, false),
Question(R.string.question_america, true),
Question(R.string.question_asia, true)
)
var currentIndex = 0
val currentQuestionAnswer: Boolean
get() = questionBank[currentIndex].answer
val currentQuestionText: Int
get() = questionBank[currentIndex].textResId
fun moveToNext(){
currentIndex = (currentIndex + 1) % questionBank.size
}
fun moveToBack(){
currentIndex = (currentIndex - 1) % questionBank.size
}
}
And my error
e: C:\Users\Jacob\AndroidStudioProjects\GeoQuiz\app\src\main\java\com\jacobjumper\geoquiz\MainActivity.kt: (54, 29): Unresolved reference: quizViewModel
just move the quizViewModel to the rest of the variables.
so like
class MainActivity : AppCompatActivity() {
private lateinit var trueButton: Button
private lateinit var falseButton: Button
private lateinit var nextButton: Button
private lateinit var prevButton: Button
private lateinit var questionTextView: TextView
private lateinit var quizViewModel: QuizViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
quizViewModel = ViewModelProvider(this).get(QuizViewModel::class.java)
Is there a way to pass a activity's function with parameter to a compose function?
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyTheme {
Main(
activityFunWithParam = activityFunWithParam // not work
)
}
}
}
fun activityFunWithParam(param: Param) {
...
}
}
#Composable
fun Main(
activityFunWithPara: (Param) -> Unit
) {
...
}
You can pass it as a method reference
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Main(activityFunWithParam = ::activityFunWithParam)
}
}
fun activityFunWithParam(param: Int) {
Toast.makeText(this, param.toString(), Toast.LENGTH_SHORT).show()
}
}
#Composable
fun Main(
activityFunWithParam: (Int) -> Unit
) {
activityFunWithParam(5)
Text(text = "Test")
}
In your example, method name itself is not a function. See https://kotlinlang.org/docs/reference/lambdas.html#instantiating-a-function-type
when i try to change orientation of the display
it will show this error "lateinit property fragmentDispatchingAndroidInjector has not been initialized"
MainActivity.kt
class MainActivity : BaseActivity(), HasSupportFragmentInjector {
#Inject
internal lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>
internal lateinit var mainMenuPagerAdapter: MainMenuPagerAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mainMenuPagerAdapter = MainMenuPagerAdapter(supportFragmentManager)
setUpMainMenuPagerAdapter()
}
override fun onFragmentAttached() {
}
override fun onFragmentDetached(tag: String) {
}
override fun supportFragmentInjector(): AndroidInjector<Fragment>? {
return fragmentDispatchingAndroidInjector
}
private fun setUpMainMenuPagerAdapter() {
mainMenuPagerAdapter.count = 1
mainMenuViewPager.adapter = mainMenuPagerAdapter
tabLayout.addTab(tabLayout.newTab().setText(R.string.my_account).setIcon(R.drawable.ic_person_white_24dp))
mainMenuViewPager.offscreenPageLimit = tabLayout.tabCount;
mainMenuViewPager.addOnPageChangeListener(TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab) {
mainMenuViewPager.currentItem = tab.position
}
override fun onTabUnselected(tab: TabLayout.Tab) {}
override fun onTabReselected(tab: TabLayout.Tab) {}
})
}
}
I had same crash when rotating screen, I was calling AndroidInjection.inject(this) after super.onCreate(savedInstanceState).
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
...
}
After this no crash. It may help.
abstract class BaseActivity : AppCompatActivity(), MVPView, BaseFragment.CallBack {
private var progressDialog: ProgressDialog? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
performDI()
}
override fun hideProgress() {
progressDialog?.let { if (it.isShowing) it.cancel() }
}
override fun showProgress() {
hideProgress()
progressDialog = CommonUtil.showLoadingDialog(this)
}
private fun performDI() = AndroidInjection.inject(this)
}
this is my BaseActivity.ky
I have OnClickInterface (with method fun onClickShape()) Main.class, and FlipFragment.class and ImageView (which called image in my code). My goal is make listener for image.
interface OnClickInterface {
fun onClickShape()
}
MainActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initTabs()
var flip = FlipFragment()
flip.listener = object : OnClickInterface {
override fun onClickShape() {
Log.d("MainActivity", "Shape Pressed")
ToastUtils.showSuccessMessage(baseContext, "sometext")
}
}
}
fun initTabs() {
var adapter = TabsPagerFragmentAdapter(supportFragmentManager)
mViewPager.adapter = adapter
mTabLayout.setupWithViewPager(mViewPager)
}
}
onCreate in FlipFragment
var image = view.findViewById<ImageView>(R.id.fShapeView)
image.setOnClickListener(View.OnClickListener {
Log.d("FlipFragment", "PRESSED")
if (listener != null)
listener!!.onClickShape()
})
App was loading well, without errors. But when I pressed in the image I show in my log FlipFragment: PRESSED that's mean that my application call method from FragmentFlip, not override method from MainActivity. Why?
I searched error . My app show NPE here.
flip.listener = object : OnClickInterface {
override fun onClickShape() {
Log.d("MainActivity", "Shape Pressed")
ToastUtils.showSuccessMessage(baseContext, "someText")
}}
Why listener = null . I defined it with anonymous class.
All code in FlipFragment
class FlipFragment : Fragment() {
private var layout = R.layout.view_flip
var listener: OnClickInterface? = null
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
var view: View
view = inflater!!.inflate(layout, container, false)
var image = view.findViewById<ImageView>(R.id.fShapeView)
image.setOnClickListener(View.OnClickListener {
Log.d("FlipFragment", "PRESSED")
if (listener != null){
listener!!.onClickShape()}
})
return view
}
companion object {
fun getInstanse(): FlipFragment {
var args = Bundle()
var flipFragment = FlipFragment()
flipFragment.arguments = args
return flipFragment
}
}
}
If you need all code it is FragmentPagerAdapter.class
class TabsPagerFragmentAdapter(fm: FragmentManager?) : FragmentPagerAdapter(fm) {
var tabs: Array<String> = arrayOf("Flip", "Multi")
override fun getItem(position: Int) = when(position){
0 -> FlipFragment.getInstanse()
1 -> Mulit.getInstanse() //it is empty now
else -> FlipFragment.getInstanse()
}
override fun getPageTitle(position: Int) = tabs[position]
override fun getCount() = tabs.size
}