I am new in Android development and I provided my code snippet.
I'm wondering why is it saying other must not be null
other = findViewById(R.id.otherId)
My Activity:
class SplashScreen : AppCompatActivity() {
lateinit var topAnimation:Animation
lateinit var bottomAnimation:Animation
lateinit var logoImage:ImageView
lateinit var bangerText:TextView
override fun onCreate(savedInstanceState: Bundle?) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_splash_screen)
topAnimation=AnimationUtils.loadAnimation(this,R.anim.top_animation)
bottomAnimation=AnimationUtils.loadAnimation(this,R.anim.bottom_animation)
logoImage=findViewById(R.id.logoImage)
bangerText=findViewById(R.id.bangerTextView)
val other=findViewById<TextView>(R.id.textView5)
logoImage.animation=topAnimation
bangerText.animation=bottomAnimation
other.animation=bottomAnimation
}
}
Can you check whether layout/activity_splash_screen.xml actually has id/textView5?
If that id is not specified in that layout, findViewById might return null
Related
The code I wrote is not working because viewbinding is not suitable. I got some help from my friend but I still couldn't do the application please help me my application is interrupted
/*MainActivity*/
class MainActivity : AppCompatActivity() {
private var _binding: ActivityMainBinding?=null//
private val binding
get()=_binding!!
override fun onCreate(savedInstanceState: Bundle?) {
_binding=ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.apply{ //5.işlemimiz ;)
editText
}
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
fun aktiviteDegistir (view:View){
val kullaniciVerisi = editText.text.toString()
val intent = Intent(applicationContext,IkinciActivity::class.java)
intent.putExtra("yollananVeri",kullaniciVerisi)
startActivity(intent)//activiteyi başlatım güzel yer
}
/*Activity2*/
val intent = intent//intent
val alinanVeri = intent.getStringExtra("yollananVeri")
textView2.text = alinanVeri
class MainActivity : AppCompatActivity() {
private var _binding: ActivityMainBinding?=null//3.islemimiz
private val binding
get()=_binding!!
override fun onCreate(savedInstanceState: Bundle?) {//4.işlemiiz
_binding=ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.apply{ //5.işlemimiz ;)
editText
}
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
After adding this code, I waited for the messages to go away, but they didn't.
my application will write something about this to the editText button will be pressed then it needs to come to the textview part in the other activity
you are following approach, that is used to bind in fragment binding. The problem is that you are setting the binding data but not connecting it with the content view. for better approach in activity view binding just the same for more cleaner activity binding.
class MainActivity : AppCompatActivity() {
private lateinit var binder : ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binder = ActivityMainBinding.inflate(layoutInflater)
setContentView(binder.root)
viewImpl()
}
/**you view calls...
* like button.setonclick() and all UI related interactions...
*/
private fun viewImpl() {
binder.run {
//here...
}
}
}
In here I have created binding lateinit var for activity binder which will be initialise when binder = ActivityMainBinding.inflate(layoutInflater) and then using that binder reference for setting my content view as setContentView(binder.root).
Happy Coding ✌️.
Why I'm getting a null string through Intent even after passing the value?
MainActivity
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding=ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.btnFirst.setOnClickListener {
val name=binding.etName.text.toString()
Intent(this,SecondActivity::class.java).also{
it.putExtra("EXTRA_NAME",name)
startActivity(it)
}
}
}
}```
SecondActivity
```class SecondActivity:AppCompatActivity() {
private lateinit var binding: ActivitySecondBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding= ActivitySecondBinding.inflate(layoutInflater)
setContentView(binding.root)
val name=intent.getStringArrayExtra("EXTRA_NAME")
val toPrint="$name hahahaha"
binding.tvNameIntent.text=toPrint
}
}
toPrint is getting "null hahahaha"
Can someone please rectify my error
You are putting in a String so you should be also reading a String and not StringArray. You can use e.g. getStringExtra() for that.
val name=intent.getStringArrayExtra("EXTRA_NAME") should be changed to
val name=intent.getStringExtra("EXTRA_NAME")
Why I have no logs by my tags? No errors or something like that.
Trying to get device info, using Kotlin.
class MainActivity : AppCompatActivity() {
var webview: WebView? = null
var _MODEL = Build.MODEL
var _MANUFACTURER = Build.MANUFACTURER
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.d("myTag", _MANUFACTURER)
Log.d("myTag2", _MODEL)
webview = findViewById<View>(R.id.browser) as WebView
webview!!.loadUrl("https://stackoverflow.com")
}
}
So I'm trying to send a text data from text entered in edit text through another activity with intent. I'm trying to send the text data from HomeActivity to SearchResultActivity. However, when I clicked the button that calls the startActivity(intent), my application forced closed and I get this exception:
2021-04-27 02:46:30.622 13861-13861/com.dicoding.movieapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.dicoding.movieapp, PID: 13861
kotlin.UninitializedPropertyAccessException: lateinit property activityHomeBinding has not been initialized
at com.dicoding.movieapp.home.HomeActivity.onClick(HomeActivity.kt:39)
at android.view.View.performClick(View.java:7500)
at android.view.View.performClickInternal(View.java:7472)
at android.view.View.access$3600(View.java:824)
at android.view.View$PerformClick.run(View.java:28657)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:239)
at android.app.ActivityThread.main(ActivityThread.java:8107)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:626)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1015)
I'm quite confused what I did wrong here. This is my code for the home activity. I have already initialized the binding in the onCreate function but why is it still saying that its uninitialized?
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val activityHomeBinding = ActivityHomeBinding.inflate(layoutInflater)
setContentView(activityHomeBinding.root)
activityHomeBinding.btnSearch.setOnClickListener(this)
}
override fun onClick(v: View?) {
when (v?.id){
R.id.btn_search -> {
val searchText = activityHomeBinding.editTextSearch.text.toString().trim()
if (searchText == null){
activityHomeBinding.editTextSearch.error = "Field cannot be empty"
} else {
val intent = Intent(this#HomeActivity, SearchResultActivity::class.java)
intent.putExtra(SearchResultActivity.EXTRA_SEARCH,searchText)
startActivity(intent)
}
}
}
And this is the code inside my SearchResultActivity:
private lateinit var searchResultActivity: ActivitySearchResultBinding
companion object {
const val EXTRA_SEARCH = "extra_search"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
searchResultActivity = ActivitySearchResultBinding.inflate(layoutInflater)
setContentView(searchResultActivity.root)
searchResultActivity.testIntent.text = intent.getStringExtra(EXTRA_SEARCH)
}
The error message points that on line 39 of your HomeActivity class, you're pointing at an uninitialized property. This is because you have defined 2 activityHomeBindings with different scopes
class HomeActivity : AppCompatActivity(), View.OnClickListener {
...
lateinit var activityHomeBinding: ActivityHomeBinding <-- 1st one, globally scoped
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val activityHomeBinding = ActivityHomeBinding.inflate(layoutInflater) <-- 2nd one, function-scoped (to onCreate)
setContentView(activityHomeBinding.root)
activityHomeBinding.btnSearch.setOnClickListener(this)
}
override fun onClick(v: View?) {
when (v?.id){
R.id.btn_search -> {
val searchText = activityHomeBinding.editTextSearch.text.toString().trim() <-- this points at 1st one, (i.e. globally scoped)
if (searchText == null){
activityHomeBinding.editTextSearch.error = "Field cannot be empty"
}
...
}
}
}
}
The solution is to simply remove val from the line where you're inflating the binding. This way, instead of creating a new variable, you're assigning the inflated binding to globally scoped lateinit var activityHomeBinding which then can be used by your onClick callback.
So make the change from
override fun onCreate(savedInstanceState: Bundle?) {
...
val activityHomeBinding = ActivityHomeBinding.inflate(layoutInflater)
...
}
to
override fun onCreate(savedInstanceState: Bundle?) {
...
activityHomeBinding = ActivityHomeBinding.inflate(layoutInflater)
...
}
I am currently working on my first Android app using Kotlin. In my activity are a lot of UI elements which I use to show dynamic information (see example below). For performance reasons I learned:
"Define a variable in the class and initialize it in the onCreate()
method."
This is kind of messy and my question is: are there other techniques to fulfill the same task but have a cleaner code? The variables are used in other methods later.
class MainActivity : AppCompatActivity() {
private lateinit var text_1: TextView
private lateinit var text_2: TextView
private lateinit var text_3: TextView
private lateinit var text_4: TextView
[...]
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
text_1 = findViewById(R.id.text1)
text_2 = findViewById(R.id.text2)
text_3 = findViewById(R.id.text3)
text_4 = findViewById(R.id.text4)
[...]
}
From ViewBinding official docs:
View binding is a feature that allows you to more easily write code that interacts with views
First, enable ViewBinding in your module:
android {
...
buildFeatures {
viewBinding true
}
}
Then, if you're calling views from activity, you should:
private lateinit var binding: ResultProfileBinding
override fun onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
binding = ResultProfileBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
}
and then you use binding instance to call the views:
binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }
If you are calling views from a fragment, you should do it like following to avoid leaks:
private var _binding: ResultProfileBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = ResultProfileBinding.inflate(inflater, container, false)
val view = binding.root
return view
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
In Kotlin you just need to use the id directly without binding. The class will import this:
import kotlinx.android.synthetic.main.<your_layout_xml>.*
In this case it will import: kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
text_1.text = "Text1"
text_2.text = "Text2"
[...]
}