How do I update the Quantity when user press "+" or "-" button? - android

Note: This has to be done in Kotlin
I want to update the quantity when the user presses the "+" or the "-" button
enter image description here
I also want the "0" (Quantity) to be aligned between the two buttons.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="36dp"
android:layout_marginTop="36dp"
android:orientation="vertical"
tools:ignore="HardcodedText">
<TextView
android:id="#+id/Quantity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="QUANTITY"
android:textSize="23sp" />
<TextView
android:id="#+id/qtr"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/Quantity"
android:layout_toRightOf="#+id/add"
android:text="#string/Qtr"
android:textSize="23sp" />
<Button
android:id="#+id/orderbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/add"
android:onClick="order"
android:text="Order" />
<Button
android:id="#+id/add"
android:layout_width="45dp"
android:layout_height="wrap_content"
android:layout_below="#+id/Quantity"
android:layout_marginRight="16dp"
android:text="+" />
<Button
android:id="#+id/sub"
android:layout_width="45dp"
android:layout_height="wrap_content"
android:layout_below="#+id/Quantity"
android:layout_marginLeft="16dp"
android:layout_toRightOf="#+id/qtr"
android:text="-" />
</RelativeLayout>
And this is the Kotlin file code (MainActivity.kt)
package com.example.demoapplicaltion
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Write code here
}
}

First create a counter above your main method:
var quantity: Int = 0
Next set the click listeners to your two buttons within your onCreate():
findViewById<Button>(R.id.add).setOnClickListener{
quantity++
updateValue()
}
findViewById<Button>(R.id.min).setOnClickListener{
quantity--
updateValue()
}
and finally create the updateValue() method:
fun updateValue(){
findViewById<TextView>(R.id.Quantity).text = quantity
}

I'll give you a step by step recepy instead of writing the whole code here.
Step 1
In your MainActivity you need some sort of reference to your two buttons and to the textview from the xml in order to do anything with them. The easiest way is to use the findViewById() fuction.
For example you would need a variable like
var addButton: Button? = null
in your Activity.
Step 2
To assgin the button from the xml to this varibale call
addButton = findViewById( R.id.add )
Step 3
Now that the button from the xml is assigned to your variable inside the activity you can access it to define what should happen if the button is clicked. Like for example:
addButton.setOnClickListener {
code that increases the quantity, sth like:
val oldQuantity = quantityTextView.text.toInt()
quantityTextView.text = oldQuantity + 1
}
To see findViewById work have a look at: https://www.tutorialkart.com/kotlin-android/access-a-view-programmatically-using-findviewbyid/
Note that there are better, but a bit more complex ways to link between xml and Activity like ViewBinding: https://developer.android.com/topic/libraries/view-binding

First get current quantity from shown textview, like this
String currentQuant = qtr.gettext().toString();
then parse into Integer
int quantity = Integer.parseInt(currentQuant);
now you have the current quantity as int just increment it, like this
quantity ++ ;
then
qtr.settext(String.valueOf(quantity));

Related

Display the text of a button when clicked in Kotlin

I have a table made of buttons and each button has a text on it. However, I want that text to be invisible unless the button is clicked.
The buttons look like this:
<Button
android:background="#drawable/roundstyle"
android:backgroundTint="#color/c1"
android:id="#+id/btnOne"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_margin="2dp"
android:layout_weight="1"
android:text="#string/i"
tools:ignore="UsingOnClickInXml"
android:onClick="displayText" />
In MainActivity, I tried to implement a function to display the text:
fun displayText(view: View) {
val b = view as Button
val buttonText = b.text.toString()
I think the easiest thing to do would be to use "if", so that if btnOne is not clicked, then the text should be invisible, else, the text should be visible. But I am not sure where to write this code in the Main Activity and how exactly, so that once the button has been clicked, the text remains on the screen.
Could someone help me with this, please?
Thank you.
can try this one by default set the button like this(the most easy solution)
<Button
android:background="#drawable/roundstyle"
android:backgroundTint="#color/c1"
android:id="#+id/btnOne"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_margin="2dp"
android:layout_weight="1"
android:tag = "some text"
tools:ignore="UsingOnClickInXml"
android:onClick="displayText" />
and click handler
fun displayText(view: View) {
val b = view as Button
val btnTag= b.tag.toString()
if (b.text.isEmpty()) {
b.text = btnTag
}
}
You can do this simply by changing the font size of the button text. you can initially set the font size to 0 and then set the right value after user clicked on it.
<Button
android:onClick="displayText"
android:text="Sample Text"
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="64dp"
android:textSize="0sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
To visible the text once
fun displayText(view: View) {
view.setTextSize(TypedValue.COMPLEX_UNIT_SP,12f)
}
This function will toggle the visibility of the text
fun displayText(view: View) {
if(view.textSize == 0f){
view.setTextSize(TypedValue.COMPLEX_UNIT_SP,12f)
}else{
view.setTextSize(TypedValue.COMPLEX_UNIT_SP,0f)
}
}

TextView background color not changing in android (kotlin) on radio button selection

I have a group of radio buttons to toggle the background color of the textview on an app.
Here is the XML for the buttons and the textview
<TextView
android:id="#+id/calcScreen"
android:layout_width="wrap_content"
android:layout_height="500dp"
android:fontFamily="monospace"
android:text="0"
android:textSize="48sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<RadioGroup
android:id="#+id/bgColorChangeGRP"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingHorizontal="14dp">
<RadioButton
android:id="#+id/_FF0000"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onRadioButtonClicked"
android:text="Red background"
android:textSize="12sp" />
<RadioButton
android:id="#+id/_00FF00"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onRadioButtonClicked"
android:text="Green background"
android:textSize="12sp" />
<RadioButton
android:id="#+id/_0000FF"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onRadioButtonClicked"
android:text="Blue background"
android:textSize="12sp" />
</RadioGroup>
</LinearLayout>
As you can see, I have a onClick method added called onRadioButtonClicked, here is the code for that function:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
fun onRadioButtonClicked(v: View){
val textView = findViewById<TextView>(R.id.calcScreen)
if (v is RadioButton) {
val checked = v.isChecked
when(v.getId()){
R.id._0000FF ->
if (checked) {
textView.setBackgroundColor(0xFF0000)
}
R.id._00FF00 ->
if (checked) {
textView.setBackgroundColor(0x00FF00)
}
R.id._0000FF ->
if (checked) {
textView.setBackgroundColor(0x0000FF)
}
}
}
}
}
Whenever I click a button nothing happens. I tried adding a print statement in testing but did not see any output in the text console. I followed the android tutorial but do not seem to get the desired output. I think it has something to do with how the onRadioButtonClicked function is getting the id's but am not 100% sure. Any tips would be appreciated.
if (checked) {
textView.setBackgroundColor(Color.parseColor("#FFFFFF"))
}
try to use it as
To clarify why your original solution wasn't working. because you made your button transparent. The first byte is the alpha.
So your colors should have value like: 0xFFFF0000 to make your colors visible. FF at the start is key.
So your code would look something like this:
fun onRadioButtonClicked(v: View){
val textView = findViewById<TextView>(R.id.calcScreen)
if (v is RadioButton) {
val checked = v.isChecked
when(v.getId()){
R.id._FF0000 ->
if (checked) {
textView.setBackgroundColor(0xFFFF0000.toInt())
}
R.id._00FF00 ->
if (checked) {
textView.setBackgroundColor(0xFF00FF00.toInt())
}
R.id._0000FF ->
if (checked) {
textView.setBackgroundColor(0xFF0000FF.toInt())
}
}
}
}

Android setclickable for custom view not work

I need to create a custom view to make a counterfeit button, and what's more, that button's enable or not depends on another checkbox.
I'd like the button stay un-clickable when the checkbox was not be checked, but it seems not work as expected.
The control logic of checkbox was in MainActivity :
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.use_so_botton)
val cusBtn = findViewById<CusButton>(R.id.cus_btn_in_use)
val chkBox = findViewById<CheckBox>(R.id.check_box_in_use)
chkBox.setOnCheckedChangeListener{
_, isChecked ->
cusBtn.isClickable = isChecked
}
cusBtn.setOnClickListener {
Toast.makeText(this#MainActivity, "Gotta you, custom view", Toast.LENGTH_LONG).show()
}
The layout of MainActivity is simple, named the ConstraintLayout to use_so_botton.xml:
<kot.bignerd.linearlay101.CusButton
android:id="#+id/cus_btn_in_use"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="66dp"
android:layout_marginEnd="66dp"
android:layout_marginStart="66dp"
android:clickable="false"
android:focusable="false"
app:image="#drawable/sun"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:text="Yo haha" />
<CheckBox
android:id="#+id/check_box_in_use"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Use!"
app:layout_constraintTop_toBottomOf="#+id/cus_btn_in_use"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="66dp"
android:layout_marginEnd="66dp"
android:layout_marginStart="66dp"
tools:layout_editor_absoluteX="68dp"
tools:layout_editor_absoluteY="117dp" />
The <kot.bignerd.linearlay101.CusButton tag inside the layout is the custom view's ConstraintLayout xml itself:
<ImageView
android:id="#+id/ImageView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:background="#drawable/budhha"
tools:src="#color/colorPrimary"
>
</ImageView>
<TextView
android:id="#+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
tools:text="Caption of the Image"
android:text="ButtText"
android:gravity="center"
app:layout_constraintStart_toEndOf="#+id/ImageView01"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:textColor="#000000">
</TextView>
And the CusButton.kt to get the parameters:
class CusButton(context: Context, attrs: AttributeSet) : ConstraintLayout(context, attrs) {
init {
View.inflate(context, R.layout.so_button, this)
val imageView: ImageView = findViewById(R.id.ImageView01)
val textView: TextView = findViewById(R.id.TextView01)
val attributes = context.obtainStyledAttributes(attrs, R.styleable.CusButton)
imageView.setImageDrawable(attributes.getDrawable(R.styleable.CusButton_image))
textView.text = attributes.getString(R.styleable.CusButton_text)
attributes.recycle()
}
}
Right now, even if the checkbox was unchecked, we could still click the button and got a toast.
I was wondering how to disable the counterfeit button until the checkbox was checked.
The answer to this problem is simply view.setEnabled(true);
Explanation:
For enabling Clicks and Touch events on any view
To Enable Click Listener Response
myView.setClickable(true);
<MyView
...
android:clickable="true"
android:focusable="true">
these attributes are gonna enable "ClickLlistener" Response. for example, Buttons are already set to be pressed and don't need any "setEnabled"
But a Custom View or just a View that isn't set to be Clicked or Touched or Pressed we need 'setEnabled' as true in code
myView.setEnabled(true);
Also, when you write view.setOnClickListener the view automatically is setEnabled(true) but clicks don't work cause it needs setClickable(true) to start listening to the response of click events

How to bind method on RadioGroup on checkChanged event with data-binding

I was searching over the internet for how to perform the new cool android data-binding over the RadioGroup and I didn't find a single blog post about it.
Its a simple scenario, based on the radio button selected, I want to attach a callback event using android data binding. I don't find any method on the xml part which allows me to define a callback.
Like here is my RadioGroup:
<RadioGroup
android:id="#+id/split_type_radio"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:checkedButton="#+id/split_type_equal"
android:gravity="center"
<!-- which tag ? -->
android:orientation="horizontal">
...
</RadioGroup>
How do I attach a handler method which will be called on RadioGroup's checkChnged event will fire using data-binding?
I have tried using onClick (don't know if it is the same) in layout file and defining method in the Activity and located it using this in the layout file:
<variable
name="handler"
type="com.example.MainActivity"/>
...
<RadioGroup
android:onClick="handler.onCustomCheckChanged"
.. >
And defined method onCustomCheckChanged like this:
public void onCustomCheckChanged(RadioGroup radio, int id) {
// ...
}
But, it gives me the compilation error:
Error:(58, 36) Listener class android.view.View.OnClickListener with method onClick did not match signature of any method handler.onCustomCheckChanged
I have seen many blogs mentioning it is possible with RadioGroup but non of them really say how. How can I handle this with data-binding ?
After digging to the bunch of methods, I found this question on SO which helped me understand how to bind single methods of listeners.
Here is what to do with RadioGroup:
In RadioGroup listener you have a method onCheckedChanged(RadioGroup g, int id). So you can directly bound that method to your handler or your activity by passing an instance of it as a variable in layout file and calling a method with the same signature.
So call on layout file like this:
<RadioGroup
android:id="#+id/split_type_radio"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:checkedButton="#+id/split_type_equal"
android:gravity="center"
android:onCheckedChanged="#{handler.onSplitTypeChanged}"
android:orientation="horizontal">
...
</RadioGroup>
And in my activity or handler, I need to simply provide the method with same name and signature like this:
public void onSplitTypeChanged(RadioGroup radioGroup,int id) {
// ...
}
Just make sure method is public.
NOTE: This works for any (most of, I have not tried all) listener methods. Like for EditText you can provide android:onTextChanged and so on.
I am using a string, and in this case I have bindable based on viewModel.getCommuteType() viewModel.setCommuteType(String)
<RadioGroup
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RadioButton
android:checked="#{viewModel.commuteType.equals(Commute.DRIVING)}"
android:onClick="#{()->viewModel.setCommuteType(Commute.DRIVING)}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="D"/>
<RadioButton
android:checked="#{viewModel.commuteType.equals(Commute.BICYCLE)}"
android:onClick="#{()->viewModel.setCommuteType(Commute.BICYCLE)}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="B"/>
<RadioButton
android:checked="#{viewModel.commuteType.equals(Commute.WALKING)}"
android:onClick="#{()->viewModel.setCommuteType(Commute.WALKING)}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="W"/>
<RadioButton
android:checked="#{viewModel.commuteType.equals(Commute.BUS)}"
android:onClick="#{()->viewModel.setCommuteType(Commute.BUS)}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="T"/>
After some hours I found easy way: two-way databinding in android. It's base skeleton with livedata and Kotlin. Also you can use ObservableField()
Set your viewmodel to data
Create your radiogroup with buttons as you like. Important: set all radio buttons id !!!
Set in your radio group two-way binding to checked variable (use viewmodel variable)
Enjoy)
layout.xml
<data>
<variable
name="VM"
type="...YourViewModel" />
</data>
<LinearLayout
android:id="#+id/settings_block_env"
...
>
<RadioGroup
android:id="#+id/env_radioGroup"
android:checkedButton="#={VM.radio_checked}">
<RadioButton
android:id="#+id/your_id1"/>
<RadioButton
android:id="#+id/your_id2" />
<RadioButton
android:id="#+id/your_id3"/>
<RadioButton
android:id="#+id/your_id4"/>
</RadioGroup>
</LinearLayout>
class YourViewModel(): ViewModel {
var radio_checked = MutableLiveData<Int>()
init{
radio_checked.postValue(R.id.your_id1)//def value
}
//other code
}
Often you care more about what was actually checked instead of "something was checked". In such case alternative solution is to ignore RadioGroup and bind all items as below:
<RadioGroup (...) >
<RadioButton (...)
android:checked="#={viewModel.optionA}"/>
<RadioButton (...)
android:checked="#={viewModel.optionB}"/>
<RadioButton (...)
android:checked="#={viewModel.optionC}"/>
</RadioGroup>
where optionA, optionB and optionC are defined in ViewModel like below:
public final ObservableBoolean optionA = new ObservableBoolean();
public final ObservableBoolean optionB = new ObservableBoolean();
public final ObservableBoolean optionC = new ObservableBoolean();
This is usually enough, however if you want to react immediately on click then you can add callBacks and use them like that:
OnPropertyChangedCallback userChoosedA = new OnPropertyChangedCallback() {
#Override
public void onPropertyChanged(Observable sender, int propertyId) {
(...) // basically propertyId can be ignored in such case
}
};
optionA.addOnPropertyChangedCallback(userChoosedA);
Advantage of such approach is that you don't need to compare and track "id".
In my current project, I did it like this.
I have three currency in the project and I choose one of them via RadioGroup.
It's enum with currencies:
enum class Currency(val value: Byte) {
USD(0),
EUR(1),
RUB(2);
companion object Create {
fun from(sourceValue: Byte): Currency = values().first { it.value == sourceValue }
fun from(sourceValue: String): Currency = values().first { it.toString() == sourceValue }
}
}
A piece of my ViewModel:
class BaseCurrencyViewModel : ViewModelBase<BaseCurrencyModelInterface>() {
/**
* Selected currency
*/
val currency: MutableLiveData<Currency> = MutableLiveData()
/**
*
*/
init {
currency.value = Currency.USD // Init value
}
}
Part of my layout (pay attention to binding in RadioGroup and tags of RadioButton):
<RadioGroup
android:id="#+id/currencySwitchers"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:selectedCurrency = "#{viewModel.currency}"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintEnd_toEndOf="parent">
<RadioButton
android:id="#+id/usdSwitcher"
android:text="USD"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:tag="USD"
/>
<RadioButton
android:id="#+id/eurSwitcher"
android:text="EUR"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:tag="EUR"
/>
<RadioButton
android:id="#+id/rubSwitcher"
android:text="RUB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:tag="RUB"
/>
</RadioGroup>
And the final part - binding adapter.
#BindingAdapter("selectedCurrency")
fun setSelectedCurrency(view: View, value: MutableLiveData<Currency>?) {
view.getParentActivity()?.let { parentActivity ->
value?.observe(parentActivity, Observer { value ->
view.findViewWithTag<RadioButton>(value.toString())
?.also {
if(!it.isChecked) {
it.isChecked = true
}
}
}
)
(view as RadioGroup).setOnCheckedChangeListener { radioGroup, checkedId ->
val currency = Currency.from(radioGroup.findViewById<RadioButton>(checkedId).tag as String)
if(value != null && value.value != currency) {
value.value = currency
}
}
}
}
In this way, I got two-way binding between RadioGroup and a property in my ViewModel.

Android using if statement on textview and imagebutton

Hello guys i am making simple game that can take point if i click right button.
so there is 5 imagebutton and 1 textview. textview will generate random number 1-5 . and those 5 imagebuttons has 5 different id , so my point is if textview generates 1 number how can i check it its right button using if statement.
if ( textview(current generated number ) == imagebutton(id) ) {
counter++)
something like this can you help me guys? example code would be nice :D
Set the tag value for the buttons
either from xml set Tag attribute
Tag = "1"
or
btn.setTag("1");
Add the buttons corresponding value to its tag and then compare it with tags value
in onClick method you get id of button clicked
Button btn = (Button) findViewById(id);
string valu = btn.getTag();
Now compare the textView value with this tag value.
string txt = textView.getText();
if(txt.equals(valu))
{
// do what you want
}
You could store the button resource IDs an array of int. Then in a common click handler, you could test whether the button clicked was the same as the one randomly selected. Here's a simplistic, minimal example. It assumes you've set and displayed the random number before you get the button clicks.
In your class, define these fields:
private int myButtons[] = null;
private int randomNumber = 0;
In onCreate(), add the following:
myButtons = new int[] {R.id.btn0, R.id.btn1, R.id.btn2, R.id.btn3, R.id.btn4};
Add the method:
public btnClick(View v) {
if (findViewById(myButtons[randomNumber]) == v)
Log.i(TAG, "Correct!");
else
Log.i(TAG, "Incorrect!");
}
Then in your layout XML, define the buttons with your click handler:
<Button
android:id="#+id/btn0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="#string/btn0" />
<Button
android:id="#+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="#string/btn1" />
<Button
android:id="#+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="#string/btn2" />
<Button
android:id="#+id/btn3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="#string/btn3" />
<Button
android:id="#+id/btn4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="#string/btn4" />

Categories

Resources