How do I change the image? - android

I am trying to change the image when I click the button, but it doesn't work. Can anyone tell me how to fix this? I think there are something to do with the declaration
val afterEatingImage:ImageView="R.drawable.after_cookie"
and I tried = (R.drawable.after_cookie), R.drawable.after_cookie, after_cookie
Maybe I should not use Val for an image but I don't know what to use. So you can see this is a basic question and I am a beginner so pls help.
fun eating(view: View?) {
val afterEatingText:String="I am so full!!"
displayMessage(afterEatingText)
val afterEatingImage:ImageView="R.drawable.after_cookie"
displayImage(afterEatingImage)
}
private fun displayMessage(message: String) {
val afterEatingText = findViewById<View>(R.id.before_eating) as TextView
afterEatingText.text = message
}
private fun displayImage(image: ImageView){
val afterEatingImage: findViewById<View>(R.id.before_cookie) as ImageView
afterEatingImage.setImageResource(image)
}
}
The id of my ImageView is android:id="#+id/before_cookie"
The names of 2 imagefiles are before_cookie and after_cookie.
Red errors are as follows.
Another way to do this:
fun eatCookie(view: View?) {
// Find a reference to the ImageView in the layout. Change the image.
val imageView = findViewById<View>(R.id.before_eating) as ImageView
imageView.setImageResource(R.drawable.after_cookie)
// Find a reference to the TextView in the layout. Change the text.
val textView = findViewById<View>(R.id.before_eating) as TextView
textView.text = "I'm so full"
}
The crash result after I click the button.
Message from Logcat
05-17 12:22:11.216 3029-3029/com.example.afterclicking E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.afterclicking, PID: 3029
java.lang.IllegalStateException: Could not find method eating(View) in a parent or ancestor Context for android:onClick attribute defined on view class com.google.android.material.button.MaterialButton
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.resolveMethod(AppCompatViewInflater.java:447)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:405)
at android.view.View.performClick(View.java:4780)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
at android.view.View$PerformClick.run(View.java:19866)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
If I use val textView = findViewById<View>(R.id.before_eating)
then red alert appears.
If I use val textView = findViewById<View>(R.id.before_eating) as TextView then it will be fine, Why is that?

What you are doing is assigning the String R.drawable.after_cookie to your ImageView afterEatingImage. You pass this ImageView to your method and try to assign it as the image resource.
What you should do is the following
Pass the integer R.drawable.after_cookie to your method
Assign this parameter to your ImageView
This will become something like this
fun eating(view: View?) {
val afterEatingText:String="I am so full!!"
displayMessage(afterEatingText)
displayImage(R.drawable.after_cookie) //Change this
}
private fun displayMessage(message: String) {
val afterEatingText = findViewById<View>(R.id.before_eating) as TextView
afterEatingText.text = message
}
private fun displayImage(imageResource: Int) { //Change this
val afterEatingImage: ImageView = findViewById<ImageView>(R.id.before_cookie)
afterEatingImage.setImageResource(imageResource)
}
Note: I am assuming this is all done in your activity. In case you are doing this in your fragment, you need a reference of your view to find your ImageView

Related

i have recently started android development and dunno where i am getting error at

I am getting some kind of empty string Amount function but dont know as im passing not null and non empty string
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val editText: EditText = findViewById(R.id.cost_of_service)
val radioGroup: RadioGroup = findViewById(R.id.tip_options)
val cal: Button = findViewById(R.id.calculate_button)
val message: String = editText.text.toString()
val tv: TextView = findViewById(R.id.tip_result)
getSignal(radioGroup, cal, message, tv)
}
private fun getSignal(radioGroup: RadioGroup, cal: Button, message: String, tv: TextView){
cal.setOnClickListener{
val selectedRB: RadioButton = findViewById(radioGroup!!.checkedRadioButtonId) //selectedRB -> selected radio button id
val per: String = selectedRB.text.toString()
val amount: Double = Amount(per, message)
tv.text = amount.toString()
}
}
private fun Amount(per: String, message: String): Double {
return message.toDouble() + (message.toInt() * per.toInt()) / 100
}
val message: String = editText.text.toString()
That gets the value of the editText at the time its called. It does not update it as it changes. Since you're calling this in onCreate, its almost certainly empty. And since it's empty, its not a numbver so trying to convert it to one fails.
The fix for this is to put this inside your onClickListener. Do the same for every field you want to get the text out of.

CameraX PreviewView to Bitmap instead of a File

I know there are other questions that was answered to many times and I tried to find the answer, but I couldn't understand of it most. I want to make the camera to take a photo, but instead of making a physical image file, I want it directly to make it into a bitmap and display it in an ImageView from a different activity, however I constantly getting the Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference, that's because of the viewFinder.bitmap is a null and decided to make a seperate function getBitmap(): Bitmap?. I don't know what it wants me to do honestly or any lead from this, all I want to do is to make the photo straight to ImageView as a bitmap. Thank you in advance.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.camerax5, PID: 5472
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.camerax5/com.example.camerax5.VirtualPreview}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3141)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3284)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1972)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7179)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
at android.content.ContextWrapper.getApplicationInfo(ContextWrapper.java:164)
at android.view.ContextThemeWrapper.getTheme(ContextThemeWrapper.java:157)
at android.content.Context.obtainStyledAttributes(Context.java:677)
at androidx.appcompat.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:842)
at androidx.appcompat.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:809)
at androidx.appcompat.app.AppCompatDelegateImpl.findViewById(AppCompatDelegateImpl.java:633)
at androidx.appcompat.app.AppCompatActivity.findViewById(AppCompatActivity.java:259)
at com.example.camerax5.MainActivity.getBitmap(MainActivity.kt:118)
at com.example.camerax5.VirtualPreview.onCreate(VirtualPreview.kt:19)
at android.app.Activity.performCreate(Activity.java:7335)
at android.app.Activity.performCreate(Activity.java:7326)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1275)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3121)
So the problem was occured on this line:
viewFinder = findViewById(R.id.previewView)
Here is the full code of what I was trying to do:
MainActivity.kt and underneath the MainActivity code is the other class with another activity to show the bitmap in the ImageView, I added this way is because I don't want to separate them and making them confusing:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewFinder = findViewById(R.id.previewView)
//Permissions
if (allPermissions()) {
startCamera()
} else {
ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS)
}
//Capture button
val captureBtn: Button = findViewById(R.id.captureButton)
captureBtn.setOnClickListener {
takePhoto()
}
outputDirectory = outputDirectoryFolder()
cameraExecutor = Executors.newSingleThreadExecutor()
}
private fun takePhoto() {
Toast.makeText(baseContext, "Processing ..", Toast.LENGTH_SHORT).show()
//Directly to open the new Activity
val intent = Intent(this, VirtualPreview::class.java)
startActivity(intent)
}
fun getBitmap(): Bitmap? {
//Preview to Bitmap
viewFinder = findViewById(R.id.previewView)
val source = viewFinder.bitmap
val newWidth = 200
val newHeight = 200
val bitmapWidth = source?.width
val bitmapHeight = source?.height
//Matrix
val matrix = Matrix()
val scaleWidth = newWidth.toFloat() / bitmapWidth!!
val scaleHeight = newHeight.toFloat() / bitmapHeight!!
matrix.postScale(scaleWidth, scaleHeight)
return Bitmap.createBitmap(source, 0, 0, newWidth, newHeight, matrix, true)
}
}
class VirtualPreview : AppCompatActivity() {
private lateinit var acceptButton: Button
private lateinit var denyButton: Button
private lateinit var imageView: ImageView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_virtual_preview)
val bitmapPreview = MainActivity().getBitmap()
val drawableBitmap = BitmapDrawable(resources, bitmapPreview)
imageView = findViewById(R.id.imagePreview)
imageView.setImageDrawable(drawableBitmap)
acceptButton = findViewById(R.id.acceptButton)
acceptButton.setOnClickListener {
}
denyButton = findViewById(R.id.denyButton)
denyButton.setOnClickListener {
//delete the matrix and returns to the main activity
finish()
}
}
}
val bitmapPreview = MainActivity().getBitmap() - This way you are creating a new instance of MainActivity and the new instance do not have any thing in preview view, also this method is not recommended. Better store bitmap inside MainActivity and then pass that bitmap to VirtualPreview activity in constructor (in bundle it won't work). It won't be a problem for your case, as you're scaling the bitmap to 200x200. and for large bitmap, store in file, and use that file. And for your case, you can create another imageview in mainactivity and show the bitmap in that imageview instead of creating another activity.

How to Delete an specific element in a Array List in Kotlin Android

I tried this in Kotli,
it works fine for the last element but not working properly for middle elements.
var dltItem = findViewById<Button>(R.id.deleteitem)
dltItem.setOnClickListener(View.OnClickListener {
for (i in 0..users.size-1) {
println("User List Size --> " + users.size)
if (users[i].isChecked) {
users.removeAt(i)
Char--
}
}
adapter.notifyDataSetChanged()
})
It is showing the error when I attempt to delete the middle element.
2021-06-24 20:33:32.272 1755-1755/com.example.gamedemokotlin E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.gamedemokotlin, PID: 1755
java.lang.IndexOutOfBoundsException: Index: 3, Size: 2
at java.util.ArrayList.get(ArrayList.java:437)
at com.example.gamedemokotlin.MainActivity$onCreate$2.onClick(MainActivity.kt:49)
at android.view.View.performClick(View.java:7184)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
at android.view.View.performClickInternal(View.java:7157)
at android.view.View.access$3500(View.java:821)
at android.view.View$PerformClick.run(View.java:27654)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:224)
at android.app.ActivityThread.main(ActivityThread.java:7561)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:995)
My Model Class
data class TodolistModel(val task_no: Int, val task: String, var isChecked: Boolean)
Adapter
class TodoAdaper(val userList: ArrayList<TodolistModel>) : RecyclerView.Adapter<TodoAdaper.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TodoAdaper.ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.row_list, parent, false)
return ViewHolder(v)
}
//this method is binding the data on the list
override fun onBindViewHolder(holder: TodoAdaper.ViewHolder, position: Int) {
val model = userList[position]
holder.tvTask.text = model.task;
holder.tvId.text = model.task_no.toString()
holder.checkBox.isChecked = model.isChecked
holder.checkBox.setOnClickListener(View.OnClickListener {
val checkBox = it as CheckBox
model.isChecked = checkBox.isChecked
userList[position] = model
notifyDataSetChanged()
})
}
//this method is giving the size of the list
override fun getItemCount(): Int {
return userList.size
}
//the class is hodling the list view
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
lateinit var tvId: TextView
lateinit var tvTask: TextView
lateinit var checkBox: CheckBox
init {
tvId = itemView.findViewById(R.id.tvId) as TextView
tvTask = itemView.findViewById(R.id.tvTask) as TextView
checkBox = itemView.findViewById(R.id.cbDone) as CheckBox
}
}
When I attempting to delete this then, It is showing error.
enter image description here
Note: working fine for the last element.
In addition to #Alex.T's answer
You can also use
users.removeAll { it.checked() }
Because removeif() is only available for API 24+
and don't forget to remove for loop.
Though there is some issue like thread-safe or not. If you want you can check this Use cases of removeall and removeif
You have a lot of Kotlin concepts quite wrong, I strongly suggest you have a read through the docs and see what methods the standard library objects have. For example not only that your for loop is completely redundant, but also you are also using it wrong.
This is how you remove based on a condition, no need to loop through a range:
users.removeIf { it.isChecked }

Is there a way to set a margin for a certain view inside a loop?

I am having a hard time putting a margin for my Cardview with a text child.
What I am trying to achieve is to dynamically create a number of cardviews based on a certain number and put them inside a layout.
Please do check my code
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
val size = NumberHolder.getSize()
val listOfNumbersLayout = findViewById<LinearLayout>(R.id.ll_list_of_numbers)
for (item in 1..size!!) {
val newCardView = CardView(this)
newCardView.foregroundGravity = Gravity.CENTER_HORIZONTAL
newCardView.setCardBackgroundColor(Color.parseColor("#FF6200EE"))
val params = newCardView.layoutParams as ViewGroup.MarginLayoutParams
params.setMargins(10,10,10,10)
newCardView.layoutParams = params
val text = TextView(this)
text.gravity = Gravity.CENTER
text.text = "test"
text.setTextColor(Color.WHITE)
newCardView.addView(text)
listOfNumbersLayout.addView(newCardView,100,100)
}
}
But I keep on having this error
java.lang.NullPointerException: null cannot be cast to non-null type android.view.ViewGroup.MarginLayoutParams
at com.fangs.number_sorter_app.NumberSorterActivity.onWindowFocusChanged(NumberSorterActivity.kt:37)
at androidx.appcompat.view.WindowCallbackWrapper.onWindowFocusChanged(WindowCallbackWrapper.java:124)
newCardView is not null but newCardView.layoutParams is null, and you are trying to cast null to a non-null type. Remember, kotlin has "nullable *types". The easy thing to do is to create
var param: MarginLayoutParams.LayoutParams =
MarginLayoutParams.LayoutParams(MarginLayoutParams.LayoutParams.WRAP_CONTENT,100);
param.setMargins(500,12,0,0)

Given text can not be applied to TextView when TextView parameters are changed

So I've made an extension to implement Precomputed Text in a TextView.
I've been getting errors though ever since I've migrated to Material Components Theme.
Here's the code below.
I've also tried migrating all TextViews, and AppCompatTextViews to MaterialTextView. Yet the issue is still occurring.
fun AppCompatTextView.setTextFuture(string: String?) {
val precomputedText =
PrecomputedTextCompat.getTextFuture(
string ?: "",
TextViewCompat.getTextMetricsParams(this),
null
)
textMetricsParamsCompat = precomputedText.get().params
setTextFuture(precomputedText)
text = string
}
fun AppCompatTextView.setTextFuture(charSequence: CharSequence?) {
val precomputedText =
PrecomputedTextCompat.getTextFuture(
charSequence ?: "",
TextViewCompat.getTextMetricsParams(this),
null
)
textMetricsParamsCompat = precomputedText.get().params
setTextFuture(precomputedText)
text = charSequence
}
fun AppCompatTextView.setTextFuture(stringResId: Int) {
val string = context.getString(stringResId)
val precomputedText =
PrecomputedTextCompat.getTextFuture(
string,
TextViewCompat.getTextMetricsParams(this),
null
)
textMetricsParamsCompat = precomputedText.get().params
setTextFuture(precomputedText)
text = string
}
The errors have been the following.
Fatal Exception: java.lang.IllegalArgumentException
Given text can not be applied to TextView.
androidx.core.widget.TextViewCompat.setPrecomputedText (TextViewCompat.java:891)
androidx.appcompat.widget.AppCompatTextView.onMeasure (AppCompatTextView.java:550)
android.view.View.measure (View.java:24953)
Fatal Exception: java.lang.IllegalArgumentException
PrecomputedText's Parameters don't match the parameters of this TextView.Consider using setTextMetricsParams(precomputedText.getParams()) to override the settings of this TextView: PrecomputedText: {textSize=49.0, textScaleX=1.0, textSkewX=0.0, letterSpacing=0.03125, textLocale=[en_GB], typeface=android.graphics.Typeface#5e608edd, variationSettings=null, elegantTextHeight=false, textDir=android.text.TextDirectionHeuristics$TextDirectionHeuristicInternal#eb941bf, breakStrategy=1, hyphenationFrequency=0}TextView: {textSize=49.0, textScaleX=1.0, textSkewX=0.0, letterSpacing=0.03125, textLocale=[en_GB], typeface=android.graphics.Typeface#5e608edd, variationSettings=null, elegantTextHeight=false, textDir=android.text.TextDirectionHeuristics$TextDirectionHeuristicInternal#eb941bf, breakStrategy=1, hyphenationFrequency=0}
android.widget.TextView.setText (TextView.java:6724)
Fatal Exception: java.lang.IllegalArgumentException
PrecomputedText's Parameters don't match the parameters of this TextView.Consider using setTextMetricsParams(precomputedText.getParams()) to override the settings of this TextView: PrecomputedText: {textSize=70.0, textScaleX=1.0, textSkewX=0.0, letterSpacing=0.03125, textLocale=[en_CA], typeface=android.graphics.Typeface#ab2ab1bb, variationSettings=null, elegantTextHeight=false, textDir=android.text.TextDirectionHeuristics$TextDirectionHeuristicInternal#34fe469, breakStrategy=1, hyphenationFrequency=0}TextView: {textSize=70.0, textScaleX=1.0, textSkewX=0.0, letterSpacing=0.03125, textLocale=[en_CA], typeface=android.graphics.Typeface#ab2ab1bb, variationSettings=null, elegantTextHeight=false, textDir=android.text.TextDirectionHeuristics$TextDirectionHeuristicInternal#34fe469, breakStrategy=1, hyphenationFrequency=0}
android.widget.TextView.setText (TextView.java:6731)
Some of my TextViews have these properties
android:ellipSize="marquee"
android:singleLine="true"
isSelected = true
all TextView layout properties must be set before creating the Params
object. If they are changed during the precomputation, this can cause
a IllegalArgumentException when the precomputed value is consumed
during measure, and doesn't reflect the TextView's current state.
https://developer.android.com/reference/androidx/core/text/PrecomputedTextCompat
so its important when you call this method: setTextFuture

Categories

Resources