I've created a custom linear layout within android studio. This layout gets inflated into another vertical layout programatically. Now I want to map a button inside this layout, which can delete the whole object. Here is my layout:
And as you can see the button "DELETE HERE" should remove the 3 items, time, weekday and the button itself.
This is my class and here
class AlarmCard #JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0,
defStyleRes: Int = 0,
) : LinearLayout(context, attrs, defStyle, defStyleRes) {
init {
LayoutInflater.from(context)
.inflate(R.layout.alarmcard, this, true)
btnDelete.setOnClickListener(){
**/* Call destructor or remove view !?!*/**
}
}
}
which get added to the linear layout with:
val monday = AlarmCard(this)
alarmCards.addView(monday)
The problem is for me how can I delete the object with a button? I tried using alarmCards.removeView(this) within btnDelete.setOnClickListener() but It crashes. :(
Thank you!!
Try this:
btnDelete.setOnClickListener {
(getParent() as? ViewGroup)?.removeView(this#AlarmCard)
}
Related
I created a custom TabLayout for my viewpage 2 and everything works fine. But I don't know how to programmatically make the text of the tabs lowercase (except for the first letter). I found a way that you can create your own style and set textAllCaps = false and pass it to the constructor. I did as follows:
class CustomTabLayout : TabLayout {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
context,
attrs,
R.style.m_tab_layout_style
)
}
And I call so:
val mTabLayout = CustomTabLayout(this, null, R.style.m_tab_layout_style)
But it doesn't work and I found information that starting from android 5 it is not possible to pass a style after constructing a view. And the correct way to solve this problem is to pass to a 4-argument constructor, for example,
RelativeLayout r = new RelativeLayout(this, null, 0, R.style.MyRelativeLayout);
But TabLayout does not have a fourth defStyleRes argument, and who can tell me how to pass the style for TabLayout programmatically or how to make the TabLayout tab text lowerCase programmatically (except for the first letter).
I want to create custom class which extends TextInputLayout and have sort of an access into its inner EditText, so I can set focus listener on it. Based on focus state and text in the EditText the error shows in TextInputLayout. Below is my current simple code where edit text is null. How can I achieve so have custom TextInputLayout that can communicate with its inner EditText ?
class CustomTextInputLayout : TextInputLayout {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
init {
Log.e("_TEST", this.editText?.toString() ?: "null") // gives null
editText?.setOnFocusChangeListener { v, hasFocus ->
if (hasfocus.not()) {
val textToCheck = editText?.text.toString()
this.error = someValidationFunction(textToCheck)
}
}
}
}
<com.app.utility.CustomTextInputLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</com.app.utility.CustomTextInputLayout>
The editText isn't initialized in init method yet. First, the parent will be laid out then the child.
Please, check this method
onLayout(boolean changed, int left, int top, int right, int bottom)
Views lifecycle is very important if you want to create custom views or viewgroups.
https://developer.android.com/reference/android/view/ViewGroup.html
Let's say the layout XML for my activity has a view like this. The XML below has a hard-coded value for the attribute, but I want to pass value from activity when setting the content view.
<myView
android:id = "#+id/myView
....
app:myAttriute = "someMode"/>
The view reads that value in the constructor like the following and sets the initial mode.
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
{
val inflater = context?.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
inflater.inflate(R.layout.myView, this);
var arr = context.obtainStyledAttributes(attrs, R.styleable.myView);
var mode = arr.getString(R.styleable.myAttribute);
Is it possible to set that attribute in the activity so that the value can be used in the view's constructor? It may sound weird, it causes some problems to change the mode after the view's constructor like this
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val myView = findView...
myView.myAttribute = "someMode";
If possible, I wish I could pass the attribute to its constructor, somehow.
super.onCreate(savedInstanceState)
//takes the view's ID and attribute name/value to be used while
//setting the content view (passed to myView's constructor)
hypotheticalMethod(R.id.myView, "myAttriute", "someMode");
setContentView(R.layout.activity_main)
As we have our App on Android O, there's a new feature introduced there, where it auto-suggest Home and Work location as per image below.
What is this called? Is there a way to disable it from our Edit Text showing it?
Apparently in Android-Oreo, there's this new feature call AUTOFILL
https://developer.android.com/guide/topics/text/autofill.html, where By default, the view uses the IMPORTANT_FOR_AUTOFILL_AUTO mode, which lets Android use its heuristics to determine if the view is important for autofill
Hence for field that is not intended to have that filled, just add the below to your view.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
setImportantForAutofill(IMPORTANT_FOR_AUTOFILL_NO);
}
Update: Found another approach to disable AUTOFILL
Use android:importantForAutofill="no" in the XML
https://developer.android.com/guide/topics/text/testautofill.html#trigger_autofill_in_your_app
Accepted answer is not a solution, it doesn't work for all cases, to Disable the Autofill completely on a particular View you should extend it and override getAutofillType() method:
class TextInputEditTextNoAutofill : TextInputEditText {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
#RequiresApi(Build.VERSION_CODES.O)
override fun getAutofillType(): Int {
return View.AUTOFILL_TYPE_NONE
}
}
This is Kotlin version, but you can get the point. Showcase repo:
https://github.com/BukT0p/AutofillBug
I'm trying to make a custom ProgressBar the way I did custom layouts a lot before. This time I'm having issues.
I can achieve the desired look with just this xml:
<ProgressBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminateOnly="false"
android:progressDrawable="#drawable/progress_bar" />
The ultimate goal, however, would be doing some of the customization in the custom class so the xml shrinks to this:
<se.my.viktklubb.app.progressbar.HorizontalProgressBar
android:id="#+id/planProgressBar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Here is the custom class:
class HorizontalProgressBar : ProgressBar {
constructor(context: Context) : super(context) {
initialSetup()
}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
initialSetup()
}
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
initialSetup()
}
fun initialSetup() {
max = 100
isIndeterminate = false
progressDrawable = context.getDrawable(R.drawable.progress_bar)
}
}
Second constructor gets fired but the bar isn't styled. It actually appears as indeterminate spinning progress and none of these setup gets applied eventually - feels like those are overriden later by something else.
What's wrong here?
DISCLAIMER:
This is a very simple example. I'm perfectly aware I could go for styles or a simple xml implementation but I just use this simple case only to demonstrate the issue.
According to the bullet 5 of this article, you may need to modify initialSetup:
fun initialSetup() {
max = 100
isIndeterminate = false
progressDrawable = context.getDrawable(R.drawable.progress_bar)
invalidate()
requestLayout()
}
If it doesn't change anything, try calling initialSetup later, on onResume of activity/fragment for example. If this work, the problem is maybe linked to the complexity of initialization/lifecycle of android components.