How to loop a set of code on Kotlin? (Android) - android

I have a button that changes the colour of a text. I want to change between the three colours. I've tried a while loop but the app simply would be blank. I've done some searching around but nothing I found worked.
Here is my MainActivity.kt code for the button:
btnChangeColor.setOnClickListener {
txtGavriel.setTextColor(Color.RED)
txtGavriel.setTextSize(TypedValue.COMPLEX_UNIT_SP, 100f)
btnChangeColor.setOnClickListener {
txtGavriel.setTextColor(Color.BLUE)
btnChangeColor.setOnClickListener {
txtGavriel.setTextColor(Color.BLACK)
}
}
}

You can do something like this:
enum class Color { // I suppose that you have already defined this enum
Blue, Red, Green
}
var state: Int = 0
val colors = Color.values()
txtGavriel.setTextSize(TypedValue.COMPLEX_UNIT_SP, 100f)
btnChangeColor.setOnClickListener {
state = (state + 1) % colors.size
txtGavriel.setTextColor(colors.get(state))
}

Related

How to change background color randomly every second programmatically in Kotlin for Android

I am working on my little Android project where the requirement is to change background color randomly every second. There is any way to do this?
Please prefer the kotlin language because I'm a beginner in development.
It is very easy but tricky.
I am using the handler Runnable method to trigger every second random function and create a new color.
you can do like this :
val colorUpdater = object:Runnable {
public override fun run() {
val random = Random()
val color = Color.argb(255, random.nextInt(256), random.nextInt(256), random.nextInt(256))
backgroundLayout.setBackgroundcolor(color)
handler.postDelayed(colorUpdater, 1000)
}
}
handler.post(colorUpdater)```

FAB not triggering inside of AlertDialog android kotlin

I have a LinearLayout with 7 FAB's inside, and I'm trying to change their background tint color by clicking, the thing is, the first FAB does trigger and change the color but the rest doesn't and also, if I click in the first FAB and then in the rest of them, they change the tint color, but doesn't trigger! I tried to debug but nothig..
This is what I did.
val monday: FloatingActionButton = dialogLayout.findViewById(R.id.monday);
val tuesday: FloatingActionButton = dialogLayout.findViewById(R.id.tuesday);
monday.setOnClickListener {
if(java.lang.String.format("#%06X", 0xFFFFFF and monday.backgroundTintList?.defaultColor!!) == "#C9C9C9"){
monday.backgroundTintList = ColorStateList.valueOf(resources.getColor(R.color.accent));
}
else{
monday.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#c9c9c9"));
}
}
tuesday.setOnClickListener {
if(java.lang.String.format("#%06X", 0xFFFFFF and monday.backgroundTintList?.defaultColor!!) == "#C9C9C9"){
tuesday.backgroundTintList = ColorStateList.valueOf(resources.getColor(R.color.accent));
}
else{
tuesday.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#c9c9c9"));
}
}
It's very weird, but I think it has to do with the view it self as if the first item registered surpass the other ones.. I don't know!
This is your problem:
tuesday.setOnClickListener {
if(java.lang.String.format("#%06X", 0xFFFFFF and ----------> monday.backgroundTintList?.defaultColor!!) == "#C9C9C9"){ <----------------------
tuesday.backgroundTintList = ColorStateList.valueOf(resources.getColor(R.color.accent));
}
else{
tuesday.backgroundTintList = ColorStateList.valueOf(Color.parseColor("#c9c9c9"));
}
}
You are comparing to Monday's state and not Tuesday's. I am guessing this happens in the rest of your buttons.

Is DrawableCompat.setTint() lazy?

I am designing an app that has 3 button in main activity, and several buttons in a fragment. I want to change the color of a button in the fragment, depending on which button of main activity is toggled.
color1.setOnClickListener {
brush_chosen = 1
color1.setBackgroundColor(R.color.black)
color2.setBackgroundColor(0x00000000)
color3.setBackgroundColor(0x00000000)
if (frag_num == 8 ){
frag_8p.set_frag_value(frag_num,brush_chosen)
}
}
The function set_frag_value is :
fun set_frag_value(frag_num:Int,brush:Int) : Int
{
brush_chosen=brush
return brush
}
This change the value of brush_chosen. Then I made a function :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
ib0.setOnClickListener { view ->
Log.d("brush_color","Brush of 0 : "+brush_chosen)
if (brush_chosen==1)
{
Log.d("brush_color","Brush Confirm : "+brush_chosen)
DrawableCompat.setTint(ib0.drawable, ContextCompat.getColor(requireContext(),R.color.rndcolor1))
}
else if (brush_chosen==2)
{
Log.d("brush_color","Brush Confirm : "+brush_chosen)
DrawableCompat.setTint(ib0.drawable, ContextCompat.getColor(requireContext(),R.color.purple_500))
}
else if (brush_chosen==3)
{
Log.d("brush_color","Brush Confirm : "+brush_chosen)
DrawableCompat.setTint(ib0.drawable, ContextCompat.getColor(requireContext(),R.color.teal_200))
}
Log.d("brush_color","End of onclicklistener ")
}
}
I checked the log and theoretically this code should work correctly. However, I found that the button color did not change properly, even I checked my app prints all log correctly. For example, when I clicked button color1 in main activity, variable brush_chosen becomes 1 and the first button in fragment I clicked changes its color. But the second button I clicked does not change its color.
Is there any problem on my code using DrawableCompat ??
Android does some Drawable state caching under the hood. You might need to call mutate() on the Drawable you want to tint and then set the new Drawable in order for the tint to show up properly.

how to set visibility GONE like android in IOS?

Anybody know a simple way to hide a label and let the other views of the screen use the place left blank ? And make the opposite when showing back that view. Something like Android setVisibility = GONE for layers.
As far as I know, using setHidden=true only hide the view from the screen but does not rearrange anything around it.
Thank you
The only way to achieve Androids .GONE functionality on iOS is to use a UIStackView
via Apples documentation
Dynamically Changing the Stack View’s Content The stack view
automatically updates its layout whenever views are added, removed or
inserted into the arrangedSubviews array, or whenever one of the
arranged subviews’s hidden property changes.
SWIFT 3:
// Appears to remove the first arranged view from the stack.
// The view is still inside the stack, it's just no longer visible, and no longer contributes to the layout.
let firstView = stackView.arrangedSubviews[0]
firstView.hidden = true
SWIFT 4:
let firstView = stackView.arrangedSubviews[0]
firstView.isHidden = true
You can achieve this easily using AutoLayout constraints.
Suppose you have three views like this:
+-----+
| A |
+-----+
+-----+
| B |
+-----+
+-----+
| C |
+-----+
and you want to make view B disappear in some cases.
Set up constraints as follows (these are just example values):
B top space to A: 4
C top space to B: 4
B height: 20
Then create an NSLayoutConstraint outlet in your code for B's height. Do this by dragging and dropping the constraint in IB.
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *bHeight;
Finally, to make the view disappear, just do the following:
self.bHeight = 0;
Note that if you are doing this for a tableview cell, you may have cases where you want B to appear in some cells, but not in others.
In this case, you will have to reset the height to its "normal" value for those cells where you want it to be visible.
self.bHeight = 24;
I was looking for simple solution and found it. I don't have to use UIStackView or create outlet for constraint. Just use this:
class GoneConstraint {
private var constraint: NSLayoutConstraint
private let prevConstant: CGFloat
init(constraint: NSLayoutConstraint) {
self.constraint = constraint
self.prevConstant = constraint.constant
}
func revert() {
self.constraint.constant = self.prevConstant
}
}
fileprivate struct AssociatedKeys {
static var widthGoneConstraint: UInt8 = 0
static var heightGoneConstraint: UInt8 = 0
}
#IBDesignable
extension UIView {
#IBInspectable
var gone: Bool {
get {
return !self.isHidden
}
set {
update(gone: newValue)
}
}
weak var widthConstraint: GoneConstraint? {
get {
return objc_getAssociatedObject(self, &AssociatedKeys.heightGoneConstraint) as? GoneConstraint
}
set(newValue) {
objc_setAssociatedObject(self, &AssociatedKeys.widthGoneConstraint, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
weak var heightConstraint: GoneConstraint? {
get {
return objc_getAssociatedObject(self, &AssociatedKeys.heightGoneConstraint) as? GoneConstraint
}
set(newValue) {
objc_setAssociatedObject(self, &AssociatedKeys.heightGoneConstraint, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
private func update(gone: Bool) {
isHidden = gone
if gone {
for constr in self.constraints {
if constr.firstAttribute == NSLayoutAttribute.width {
self.widthConstraint = GoneConstraint(constraint: constr)
}
if constr.firstAttribute == NSLayoutAttribute.height {
self.heightConstraint = GoneConstraint(constraint: constr)
}
constr.constant = 0
}
} else {
widthConstraint?.revert()
heightConstraint?.revert()
}
}
}
Now, you can call view.gone = true and that's it.
You can use UIStackView if youe app supports ios 9 and above.
but if your app support ios 8 also than You have to achive it using Autolayout and add Height Constrain for View
So if you want hide than just set height constrain value 0.

Xamarin.Forms: wrong button text alignment after click (Android)

I have a problem with Xamarin.Forms (version 1.2.2) on Android (Nexus 5).
The alignment of Button.Text is often not centered after performing a click.
In a short project, I figured out, that updating the UI causes the problem.
public class App
{
public static Page GetMainPage()
{
var label = new Label {
Text = "label",
};
var buttonBad = new Button {
Text = "buttonBad",
Command = new Command(() => label.Text += "1"),
};
var buttonGood = new Button {
Text = "buttonGood",
};
return new ContentPage {
Content = new StackLayout {
Children = {
buttonBad,
buttonGood,
label,
}
}
};
}
}
A click on "buttonBad" (updating the label.Text) causes the text-alignment of this button to not be centered anymore. A click on "buttonGood" does not cause the problem.
Is there a good workaround to solve this problem?
This workaround seems to be too complicated:
http://forums.xamarin.com/discussion/20608/fix-for-button-layout-bug-on-android
edit:
A programatically edit of the UI also cases the bug. Changing the label.Text in an async method after a short waiting leads the "buttonGood" to align its text wrong after a click.
edit2:
I created an example / test project on GitHub:
https://github.com/perpetual-mobile/ButtonTextAlignmentBug.git
The alignment is correct, when the StackLayout is replaced by an AbsolutLayout, but i need the StackLayout to work well.
Ok, after hours of dealing with this silly bug, I resolved it by implementing a custom renderer and overriding ChildDrawableStateChanged:
public override void ChildDrawableStateChanged(Android.Views.View child)
{
base.ChildDrawableStateChanged(child);
Control.Text = Control.Text;
}

Categories

Resources