Android setclickable for custom view not work - android

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

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())
}
}
}
}

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

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));

How to perform a check in checkbox clicking on entire recyclerview row

Now I register each checkbox click each time y press on the checkbox like this
inner class OrdersInnerViewHolder(itemView: View): BaseViewHolder<Cart>(itemView){
override fun bind(item: Cart, position: Int) {
itemView.checkBox.setOnCheckedChangeListener { buttonView, isChecked ->
item.isChecked = isChecked
if(isChecked){
map.put(position,true)
}else{
map.remove(position,true)
}
}
}
}
I plan to click the whole row to check or uncheck my item, now I know how to perform the click on the entire row but no how to set the checked changed listener
inner class OrdersInnerViewHolder(itemView: View): BaseViewHolder<Cart>(itemView){
override fun bind(item: Cart, position: Int) {
itemView.setOnClickListener {
//How to perform checkbox check and uncheck clicking on the entire row instead of the checkbox ?
}
itemView.checkBox.setOnCheckedChangeListener { buttonView, isChecked ->
item.isChecked = isChecked
if(isChecked){
map.put(position,true)
}else{
map.remove(position,true)
}
}
}
}
Since the checkbox has the checked listener I do not have a way to interact with it when clicking the whole view
I plan to let my user click the checkbox and also the whole row to select or unselect this checkbox
XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:weightSum="3"
android:orientation="horizontal">
<CheckBox
android:id="#+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/item_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginBottom="16dp"
android:text="Test " />
<TextView
android:id="#+id/item_qty"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_weight="1"
android:text="Qty: 2" />
<TextView
android:id="#+id/item_price"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_weight="1"
tools:text="$100.00"/>
</LinearLayout>
Any ideas?
Add an OnClickListener to the parent view that toggles the CheckBox. The OnCheckedChangeListener will still get called in response to the parent view's click listener changing the checked state:
itemView.setOnClickListener {
itemView.checkBox.isChecked = !itemView.checkBox.isChecked
}
To get the parent view to look and behave correctly, you can add these to its element in the XML:
android:background="?android:attr/selectableItemBackground"
android:clipToPadding="false"
android:focusable="true"
IIRC, adding the OnCheckedChangeListener to the CheckBox automatically makes it clickable. You might consider setting itemView.checkBox.isClickable = false right after setting the listener so your whole list item will show the ripple effect even if you tap over the CheckBox.
Side note: Don't forget to set the initial state of the CheckBox in onBindView:
itemView.checkBox.isChecked = item.isChecked
It will have an unpredictable state when it scrolls onto the screen, otherwise!
Firstly add id in your LinearLayout then declare then in java
Then change your code according to mine:
inner class OrdersInnerViewHolder(itemView: View): BaseViewHolder<Cart>(itemView){
override fun bind(item: Cart, position: Int) {
itemView.setOnClickListener {
//How to perform checkbox check and uncheck clicking on the entire row instead of the checkbox ?
}
linearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(itemView.checkBox.isChecked){
map.put(position,true)
}else{
map.remove(position,true)
}
}
});
}
}
}

Creating a Radio-style Preference

I'm trying to create a Radio-style Preference where the user can click an option which is then assigned as the new value of the Preference:
however when I click one option is selects all 3 options:
Here is my layout:
preferences.xml
<Preference
android:layout="#layout/preference_gender"
android:key="seeking"
android:title="Seeking"/>
preference_gender.xml
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/seeking"
android:singleLine="true"
android:padding="10dp"
android:textSize="20sp"
android:textColor="#color/colorIcons"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#id/male"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/male"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="#id/female"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:textSize="#dimen/settings_textSize"
android:text="Male"
android:gravity="center"
android:background="#drawable/settings_gender"
android:padding="#dimen/settings_box_selection_padding"
android:paddingStart="#dimen/button_horizontal_padding"
android:paddingEnd="#dimen/button_horizontal_padding"
android:textColor="#color/colorPrimaryDark"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/female"
app:layout_constraintStart_toEndOf="#+id/male"
app:layout_constraintEnd_toStartOf="#id/both"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:textSize="#dimen/settings_textSize"
android:text="Female"
android:gravity="center"
android:padding="#dimen/settings_box_selection_padding"
android:background="#drawable/settings_gender"
android:paddingStart="#dimen/button_horizontal_padding"
android:paddingEnd="#dimen/button_horizontal_padding"
android:textColor="#color/colorPrimaryDark"/>
<androidx.appcompat.widget.AppCompatTextView
app:layout_constraintStart_toEndOf="#id/female"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:id="#+id/both"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:textSize="#dimen/settings_textSize"
android:text="Both"
android:gravity="center"
android:padding="#dimen/settings_box_selection_padding"
android:background="#drawable/settings_gender"
android:paddingStart="#dimen/button_horizontal_padding"
android:paddingEnd="#dimen/button_horizontal_padding"
android:textColor="#color/colorPrimaryDark"/>
</androidx.constraintlayout.widget.ConstraintLayout>
So I want to be able to click a textview and then get the value of that in Preference.OnPreferenceClickListener.
Any idea how?
EDIT:
class PreferencesFragment : PreferenceFragmentCompat(), View.OnClickListener {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val genderPreference: Preference = findPreference("seeking")!!
val parentView = listView.getChildAt(genderPreference.order)
val childView = parentView.findViewById<TextView>(R.id.male) // NullPointerException
}
override fun onClick(v: View?) {
Log.d(TAG, "clicked") // doesn't log
when (v?.id){
R.id.male -> Log.d(TAG, "male")
}
}
}
That's probably because all three buttons are under one preference item, when you set an OnPreferenceClickListener, it selects the entire preference with the layout you included as a whole.
So, instead of setting an OnPreferenceClickListener you should try getting the parent view and setting the click listeners on these TextViews individually and from there update the preference's value.
Or you can just set the onClick attributes of each TextView in the layout xml file to your desired functions.
To get the View of this preference, you can use something like
View preferenceView = getListView().getChildAt(preference.getOrder());
Or, use the getView method and supply both parameters with null:
View preferenceView = preference.getView(null, null);
If you are using the AndroidX library for preference, then there's no getView method, so the only option would be creating a custom Preference class and deal with the views there:
public class CustomPreference extends Preference {
public CustomPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onBindView(View rootView) {
super.onBindView(rootView);
View myView = rootView.findViewById(R.id.myViewId);
// get your textViews from myView
TextView maleText = myView.findViewById(R.id.male);
...
}
}
Then use it in your preference.xml like this:
<your.package.CustomPreference
android:key="your_key"
android:layout="#layout/your_layout" />

Categories

Resources