OnClick Listeners in include layout - android

I have a layout which contains an edittext and two button for increment and decrement of the value in editext. Now I am using include to use this button in my activity as I am having multiple use of that.
eg :-
<include
android:id="#+id/editTextOne"
layout="#layout/include_edittext_with_buttons"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<include
android:id="#+id/editTextTwo"
layout="#layout/include_edittext_with_buttons"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
I can get the onClick events of my increment and decrement buttons but I don't understand how will i catch that the onClick of the particular include has been clicked. ?
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatEditText
android:id="#+id/editText"
android:layout_width="#dimen/_120sdp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="#+id/btnPlus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="#dimen/_10sdp"
android:onClick="onClick"
app:layout_constraintBottom_toBottomOf="#id/editText"
app:layout_constraintEnd_toEndOf="#id/editText"
app:layout_constraintTop_toTopOf="#id/editText" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="#+id/btnMinus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/_10sdp"
android:onClick="onClick"
app:layout_constraintBottom_toBottomOf="#id/editText"
app:layout_constraintStart_toStartOf="#id/editText"
app:layout_constraintTop_toTopOf="#id/editText" />
</androidx.constraintlayout.widget.ConstraintLayout>
NOTE :- I get that working using binding. editTextOne.btnPlus.setOnClickListener { Toast.makeText(this, "Plus", Toast.LENGTH_SHORT).show() } and similar for the other's but what i want is I can write the plus and minus click listener once and then they update the values of the edittext in which they are included only.
Not sure if that would be possible any better suggestions ?

there is a solution for solving this problem.
first, assign an id for each of the includes.
<include
android:id="#+id/inc1"
layout="#layout/include_layout"
...
/>
<include
android:id="#+id/inc2"
layout="#layout/include_layout"
...
/>
then add oclick in view's xml code.
//include_layout.xml"
<androidx.appcompat.widget.AppCompatImageButton
android:id="#+id/ib"
android:onClick="onClick"
...
/>
after implementing onClick function in your code you can specify which view exactly clicked by checking its parent id.
public void onClick(View view) {
if (view.getId() == R.id.ib) {
int parent_id = ((View) view.getParent()).getId();
if (parent_id == R.id.inc1) {
//clicked view in first include
}
else if (parent_id == R.id.inc2) {
//clicked view in second include
}
}
}

You can get views like that.
// First View
val includedView1 = findViewById<ConstraintLayout>(R.id.editTextOne)
val btnPlus1 = includedView1.findViewById<Button>(R.id.btnPlus)
val btnMinus1 = includedView1.findViewById<Button>(R.id.btnMinus)
// Second View
val includedView2 = findViewById<ConstraintLayout>(R.id.editTextTwo)
val btnPlus2 = includedView2.findViewById<Button>(R.id.btnPlus)
val btnMinus2 = includedView2.findViewById<Button>(R.id.btnMinus)

Related

TextView Edit Text is not responding to Click Events

I have a layout with three TextViews, two TextViews are responding to Click Events but the last one is not responding. I am using Navigation to navigate to other fragments. The OnClick method is called inside an adapter which implements view.OnClickListener.
XML
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_marginStart="#dimen/defaultMargin"
android:layout_height="wrap_content">
<TextView
android:text="How CADO works"
style="#style/CircularBook"
android:drawableEnd="#drawable/arrow_right"
android:layout_width="0dp"
android:layout_height="#dimen/buttonHeight"
android:id="#+id/howCadoWorks"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<View
app:layout_constraintTop_toBottomOf="#id/howCadoWorks"
android:layout_width="match_parent"
android:background="#color/pinkishGray"
android:layout_height="0.5dp"
android:id="#+id/view3"></View>
<TextView
android:text="FAQ"
style="#style/CircularBook"
android:layout_width="0dp"
android:drawableEnd="#drawable/arrow_right"
android:layout_height="#dimen/buttonHeight"
android:id="#+id/faqs"
app:layout_constraintTop_toBottomOf="#+id/view3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<View
app:layout_constraintTop_toBottomOf="#id/faqs"
android:layout_width="match_parent"
android:background="#color/pinkishGray"
android:layout_height="0.5dp"
android:id="#+id/view4"></View>
<TextView
android:text="Contact Us"
android:drawableEnd="#drawable/arrow_right"
style="#style/CircularBook"
android:layout_width="0dp"
android:layout_height="#dimen/buttonHeight"
android:id="#+id/contactus"
app:layout_constraintTop_toBottomOf="#+id/view4"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
OnClickMethod
public void onClick(#Nullable View view) {
NavController var3 = Navigation.findNavController(view);
if(view.getId()==R.id.contactus){
**var3.navigate(R.id.contactus_fragment);**
return;
}
else if (view.getId()==R.id.faqs){
var3.navigate(R.id.faqFragmnt);
return;
}
else if (view.getId()==R.id.howCadoWorks){
Toast.makeText(view.getContext(),"Feature is in Progress", Toast.LENGTH_SHORT).show();
// var3.navigate(R.id.contactus_fragment);
return;
}
else
{
}
}
I have tried multiple ways, rechecked id's as well but nothing is working.
as #Nilesh Rathod said, you need to make sure that all your text view have set an on click listener like:
textView.setOnClickListener(this);
or you can also:
textView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Here you put the code you want to use for the specific textView click event
}
});

How to set some action in generated buttons inside custom Adapter

I got the following composition:
This layout is an Item of my RecyclerView.Adapter. The X button (holder.delete_button), when clicked, deletes himself and the EditText; basically it removes the row.
The ADD FIELD button add new rows (by inflater):
Here's the code to add new line:
holder.add_field_button.setOnClickListener {
holder.parent_layout.apply {
val inflater = LayoutInflater.from(context)
val rowView = inflater.inflate(R.layout.generated_layout, this, false)
holder.parent_layout.addView(rowView, holder.parent_layout.childCount!! - 0)
}
}
My problem here is that I just can delete the first row, because is the only button I can initialize in the ViewHolder by the id of delete_button. But for the next X buttons, I can't do no action, because the button it's in an external layout inflated, called generated_layout! I've tried to generate ids but then I don't know how to put them into an array. Here's the code to delete a row:
holder.delete_button.setOnClickListener{
holder.parent_layout.removeView(holder.delete_button.parent as View)
}
Here's the code of generated_layout, as well:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal" >
<EditText
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="5"
android:inputType="phone"/>
<Button
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_weight="0"
android:background="#android:drawable/ic_delete"/>
</LinearLayout>
Set the onClick listener like this
holder.add_field_button.setOnClickListener {
holder.parent_layout.apply {
val inflater = LayoutInflater.from(context)
val rowView = inflater.inflate(R.layout.generated_layout, this, false)
val rowViewDeleteButton=rowView.findViewById(R.id.deletebutton)
rowViewDeleteButton.setOnClickListener{
holder.parent_layout.removeView(it.parent as View)
}
holder.parent_layout.addView(rowView, holder.parent_layout.childCount!! - 0)
}
}
And give id to your delete button :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal" >
<EditText
android:id="#+id/text"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="5"
android:inputType="phone"/>
<Button
android:id="#+id/deletebutton"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_weight="0"
android:background="#android:drawable/ic_delete"/>
</LinearLayout>

Cannot Click List Item in HorizontalScrollView

I'm noticing that by adding the HorizontalScrollView it's disabling my ability to select items on my ListView. This seems like a pretty basic/common feature to want to add (I want to be able to swipe my item to the left to offer a delete option) but HorizontalScrollView appears to be incompatible with items that you would like to also touch to select. Note that if I change HorizontalScrollView to a LinearLayout or otherwise the items become selectable.
I was suspecting that touch listeners may be ineffective due to the fact that the swiping capability overrides any other kind of touch, but I can't really think of why it doesn't work otherwise. Can anyone help to resolve this issue? I would like to be able to use HorizontalScrollView alongside a click compatibility (unless there is another way to achieve the same functionality).
<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<android.support.constraint.ConstraintLayout
android:id="#+id/constraintLayout4"
android:layout_width="384dp"
android:layout_height="110dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/task_view_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="17dp"
android:layout_marginTop="28dp"
android:fontFamily="#font/robotolight"
android:text="#string/task_name"
android:textColor="#android:color/black"
android:textSize="24sp"
app:layout_constraintStart_toEndOf="#+id/task_view_icon"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/task_view_icon"
android:layout_width="77dp"
android:layout_height="77dp"
android:layout_marginStart="17dp"
android:layout_marginTop="17dp"
android:contentDescription="#+string/icon"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/main_page_icon_switch_x4" />
<TextView
android:id="#+id/task_view_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="50dp"
android:layout_marginTop="36dp"
android:fontFamily="#font/robotolight"
android:text="#string/duration"
android:textColor="#android:color/black"
android:textSize="14sp"
app:layout_constraintStart_toEndOf="#+id/task_view_name"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/task_view_detail"
android:layout_width="228dp"
android:layout_height="31dp"
android:layout_marginStart="17dp"
android:fontFamily="#font/robotolight"
android:text="#string/task_view_detail_literal"
android:textColor="#android:color/black"
android:textSize="12sp"
app:layout_constraintStart_toEndOf="#+id/task_view_icon"
app:layout_constraintTop_toBottomOf="#+id/task_view_name" />
</android.support.constraint.ConstraintLayout>
<android.support.constraint.ConstraintLayout
android:id="#+id/task_delete"
android:layout_width="116dp"
android:layout_height="110dp"
android:background="#color/colorPrimary"
app:layout_constraintEnd_toEndOf="#id/constraintLayout4"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/task_delete_literal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="13dp"
android:layout_marginTop="39dp"
android:fontFamily="#font/roboto_regular"
android:text="#string/delete"
android:textColor="#android:color/background_light"
android:textSize="24sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</LinearLayout>
</HorizontalScrollView>
For anyone having this problem, I managed to find a way to workaround this. My problem was that I could not click on the ListView item because of the HorizontalScrollView setup in the XML, however in my case I was using an adapter along with my ListView (that allows you link your listView with your actual list row view) and in that adapter I simply defined and linked the container of the view that I want to press and set an onClickListener.
This goes in your custom adapter:
ConstraintLayout myLayout = convertView.findViewById(R.id.constraintLayout1);
ConstraintLayout anotherLayout = convertView.findViewById(R.id.constraintLayout2); //lets' say I'm using this to delete the item when clicked
myLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent exampleIntent = new Intent(viewParent.getContext(), SomeActivity.class);
}
});
anotherLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
android.support.v7.app.AlertDialog.Builder builder = new android.support.v7.app.AlertDialog.Builder(view.getContext());
builder.setMessage("Are You Sure?").setNegativeButton("No", null);
builder.setPositiveButton("yes", new android.support.v7.app.AlertDialog.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Database database = new Database(viewParent.getContext());
database.deleteItem(item);
List<Item> items = database.getItems();
ListView list = (ListView) viewParent.findViewById(R.id.my_linear_list);
//List<Item> items = new Database(viewParent.getContext()).getItems();
TaskAdapter adapterNew = new ItemAdapter(viewParent.getContext(), tasks);
list.setAdapter(adapterNew);
}
});
builder.show();
}
});

How to overlay a view in a constraintlayout?

I have this layout of my login activity. I want to overlay progressBar as like it can be done using FrameLayout. How to do this using ConstraintLayout?
<layout>
<data>
<variable
name="vm"
type="com.app.android.login.vm" />
</data>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
tools:context="com.app.android.login.LoginActivity"
tools:ignore="missingPrefix">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="#dimen/default_view_margin_bottom_8dp">
<android.support.design.widget.TextInputLayout
android:id="#+id/til_login_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="#dimen/default_view_margin_right_8dp"
android:layout_marginStart="#dimen/default_view_margin_left_8dp"
android:textColorHint="#color/colorSecondaryText"
app:hintTextAppearance="#style/AppTheme.InputLayoutStyle"
app:layout_constraintBottom_toTopOf="#+id/til_login_password"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/login_email"
android:imeOptions="actionNext"
android:singleLine="true"
android:text="#={vm.emailField}"
android:textColor="#color/colorPrimaryText" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="#+id/til_login_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="#dimen/default_view_margin_right_8dp"
android:layout_marginStart="#dimen/default_view_margin_left_8dp"
android:textColorHint="#color/colorSecondaryText"
app:hintTextAppearance="#style/AppTheme.InputLayoutStyle"
app:layout_constraintBottom_toTopOf="#+id/btn_login_login"
app:layout_constraintTop_toBottomOf="#+id/til_login_email"
app:layout_constraintVertical_chainStyle="packed">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/login_password"
android:imeOptions="actionDone"
android:inputType="textPassword"
android:singleLine="true"
android:text="#={vm.passwordField}"
android:textColor="#color/colorPrimaryText" />
</android.support.design.widget.TextInputLayout>
<Button
android:id="#+id/btn_login_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="#dimen/default_view_margin_right_8dp"
android:layout_marginStart="#dimen/default_view_margin_left_8dp"
android:layout_marginTop="48dp"
android:onClick="#{vm::login}"
android:text="#string/login_btn_text"
android:textColor="#color/colorWhite"
app:layout_constraintBottom_toTopOf="#+id/textview_login_forgot_password"
app:layout_constraintTop_toBottomOf="#+id/til_login_password"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="#+id/textview_login_forgot_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="#dimen/default_view_margin_right_8dp"
android:layout_marginStart="#dimen/default_view_margin_left_8dp"
android:layout_marginTop="36dp"
android:gravity="center"
android:text="#string/login_forgot_password"
app:layout_constraintBottom_toTopOf="#+id/btn_login_register"
app:layout_constraintTop_toBottomOf="#+id/btn_login_login"
app:layout_constraintVertical_chainStyle="packed" />
<Button
android:id="#+id/btn_login_register"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="#dimen/default_view_margin_right_8dp"
android:layout_marginStart="#dimen/default_view_margin_left_8dp"
android:text="#string/login_sign_up"
android:textColor="#color/colorWhite"
app:layout_constraintBottom_toBottomOf="parent" />
<ProgressBar
android:id="#+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="#{vm.progressVisibility}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</ScrollView>
</layout>
It looks like this:
I am looking for solution which should work for API level 19+. I don't want to add more hierarchy in my layout by wrapping Button or ProgressBar inside ViewGroup or so.
There are two options, in each case you add one attribute to your <ProgressBar/> tag. It is either
android:translationZ="2dp"
or
android:elevation="2dp"
API level must be >= 21.
If you want to 100% overlay the target view, constrain all the sides of the overlaying view to the corresponding sides of the target view and set the height and width of the overlaying view to 0dp like the following:
<View
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="#id/animation_view"
app:layout_constraintLeft_toLeftOf="#id/animation_view"
app:layout_constraintRight_toRightOf="#id/animation_view"
app:layout_constraintTop_toTopOf="#id/animation_view"/>
Here is a working example. In the following image, a red scrim is placed over an image. The XML follows the image.
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/animation_view"
android:layout_width="250dp"
android:layout_height="250dp"
android:src="#mipmap/ic_launcher"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#AAFF0000"
app:layout_constraintBottom_toBottomOf="#id/animation_view"
app:layout_constraintLeft_toLeftOf="#id/animation_view"
app:layout_constraintRight_toRightOf="#id/animation_view"
app:layout_constraintTop_toTopOf="#id/animation_view" />
</android.support.constraint.ConstraintLayout>
See the documentation for ConstraintLayout for more information.
Set an elevation on the ProgressBar 2dp seems to work.
android:elevation="2dp"
You could also try setting translationZ as suggested in the answer to a similar question. For me this works on an emulator running API 17 and the progress bar appeared on top as expected. If you get any warning than check your build version
In my observations Android "stacks" the views along the z-axis in the order they appear in the xml file in that the view at the end of the file will be at the top of the z-axis and the view at the start of the file will be at the bottom. Of course once you start setting elevation and zTranslation etc the z-axis stack order will be affected...
so moving the progressBar declaration to the end of the ConstraintLayout should make it appear above the other views, this has worked for me.
Here is your API 19 solution. It puts a CircularProgressDrawable in an overlay on top of your ConstraintLayout.
This is what it looks like:
What you have to do is:
Get rid of the XML ProgressBar.
Give your XML ConstraintLayout an id, for example:
android:id="#+id/cl"
Add this code to your MainActivity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
boolean toggle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ConstraintLayout cl = findViewById(R.id.cl);
cl.setOnClickListener(this);
}
#Override
public void onClick(final View view) {
toggle ^= true;
if (toggle) {
startProgress();
} else {
stopProgress();
}
}
void startProgress() {
final ConstraintLayout cl = findViewById(R.id.cl);
final CircularProgressDrawable progressDrawable = new CircularProgressDrawable(this);
progressDrawable.setColorSchemeColors(Color.MAGENTA);
progressDrawable.setCenterRadius(50f);
progressDrawable.setStrokeWidth(12f);
progressDrawable.setStrokeCap(Paint.Cap.BUTT);
cl.post(new Runnable() {
#Override
public void run() {
progressDrawable.setBounds(0, 0, cl.getWidth(), cl.getHeight());
cl.getOverlay().add(progressDrawable);
}
});
progressDrawable.start();
}
void stopProgress() {
final ConstraintLayout cl = findViewById(R.id.cl);
final CircularProgressDrawable progressDrawable = new CircularProgressDrawable(this);
progressDrawable.setColorSchemeColors(Color.MAGENTA);
progressDrawable.setCenterRadius(50f);
progressDrawable.setStrokeWidth(12f);
progressDrawable.setStrokeCap(Paint.Cap.BUTT);
cl.post(new Runnable() {
#Override
public void run() {
cl.getOverlay().clear();
}
});
progressDrawable.stop();
}
}
I want to provide you with an alternative to the XML solution.
You can also add a view programmatically to your root view. (ConstraintLayout)
ViewGroupOverlay is an extra layer that sits on top of a ViewGroup (the "host view") which is drawn after all other content in that view (including the view group's children). Interaction with the overlay layer is done by adding and removing views and drawables.
<android.support.constraint.ConstraintLayout
android:id="#+id/root_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="#dimen/default_view_margin_bottom_8dp">
If you reference the root in your code you can then add your ProgressBar.
Something like this:
rootLayout.overlay.add(ProgressBar(context).apply {
measure(View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY))
layout(0, 0, 100, 100)
})
You can also check out this link for extra info.
And this SO question can also help.
You could try one of these options:
1. Add a relative layout outside your layout as here
<RelativeLayout
android:id="#+id/relativelayout_progress"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:background="#aa000022" >
<ProgressBar
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateOnly="true" />
</RelativeLayout>
Add a view overlay in your activity's onCreate as described here Android 4.3 User Interface View overlays
Another easy way to solve this is to change Button to View, change background and size. Overlay it with TextView for replacing old Button text and another View for clickable later
You can achieve your goal by setting the Z translation for the view.
Put this method in a helper class (for example: UIUtils) and use it for your view:
/**
* Set the 'Z' translation for a view
*
* #param view {#link View} to set 'Z' translation for
* #param translationZ 'Z' translation as float
*/
public static void setTranslationZ(View view, float translationZ) {
ViewCompat.setTranslationZ(view, translationZ);
}
USAGE:
UIUTils.setTranslationZ(YOUR_VIEW, 5);
Updated Solution for 2020
Kotlin language
I have 2 scenarios, the first is just a normal button and the second one is
progress on the center of the button with preventing the click action
here is just shortcode if you want to know how I handle button and progress bar
Use jsut these two method if you want get an idea
private fun disableButton() {
button.run {
preservedButtonText = text.toString()
text = ""
isClickable = true
isEnabled = false
}
progressBar.visibility = View.VISIBLE
}
private fun enableButton() {
button.run {
text = preservedButtonText
isClickable = false
}
progressBar.visibility = View.INVISIBLE
}
and surprise is had for you a class that does all the stuff you just use it
I handle create parent constraint layout and it's child's (button, progress bar)
programmatically
/**
* Created by Amirahmad Adibi.
* XProject | Copyrights 2019-12-16.
*/
class ZProgressButton(context: Context, var attributeSet: AttributeSet) :
ConstraintLayout(context, attributeSet) {
var isLoading: Boolean = false
set(value) {
handelShowing(value)
field = value
}
var preservedButtonText: String = ""
var button: Button
var progressBar: ProgressBar
init {
resetPadding()
button = getButton(context, attributeSet)
progressBar = getProgressBar(context, attributeSet)
preservedButtonText = button.text.toString()
addView(button)
addView(progressBar)
#RequiresApi(Build.VERSION_CODES.LOLLIPOP)
progressBar.elevation = 2f
ViewCompat.setTranslationZ(progressBar, 5f)
ViewCompat.setTranslationZ(button, 1f)
handleConstraint(this, button, progressBar)
}
private fun handleConstraint(
view: ConstraintLayout,
button: Button,
progressBar: ProgressBar
) {
with(ConstraintSet()) {
clone(view)
connect(button.id, ConstraintSet.RIGHT, view.id, ConstraintSet.RIGHT)
connect(button.id, ConstraintSet.LEFT, view.id, ConstraintSet.LEFT)
connect(button.id, ConstraintSet.TOP, view.id, ConstraintSet.TOP)
connect(button.id, ConstraintSet.BOTTOM, view.id, ConstraintSet.BOTTOM)
connect(progressBar.id, ConstraintSet.RIGHT, view.id, ConstraintSet.RIGHT)
connect(progressBar.id, ConstraintSet.LEFT, view.id, ConstraintSet.LEFT)
connect(progressBenter code herear.id, ConstraintSet.TOP, view.id, ConstraintSet.TOP)
connect(progressBar.id, ConstraintSet.BOTTOM, view.id, ConstraintSet.BOTTOM)
applyTo(view)
}
}
private fun getButton(context: Context, attributeSet: AttributeSet): Button {
return ZButton(context, attributeSet).run {
id = View.generateViewId()
text = "text"
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
isClickable = true
return#run this
}
}
private fun getProgressBar(context: Context, attributeSet: AttributeSet): ProgressBar {
return ProgressBar(context, attributeSet).run {
id = View.generateViewId()
visibility = View.VISIBLE
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
setPadding(4, 4, 4, 4)
return#run this
}
}
fun resetPadding() {
setPadding(0, 0, 0, 0)
}
fun handelShowing(value: Boolean) {
removeView(button)
removeView(progressBar)
if (value) {
disableButton()
} else {
enableButton()
}
addView(button)
addView(progressBar)
}
private fun disableButton() {
button.run {
preservedButtonText = text.toString()
text = ""
isClickable = true
isEnabled = false
}
progressBar.visibility = View.VISIBLE
}
private fun enableButton() {
button.run {
text = preservedButtonText
isClickable = false
}
progressBar.visibility = View.INVISIBLE
}
}
Usage :
buttonLoading.setOnClickListener {
progressButton.isLoading = true
}
buttonDone.setOnClickListener {
progressButton.isLoading = false
}
android:elevation is not working in API level 19. A simple trick will be used to use a card view and set the elevation of this card
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/white"
android:padding="#dimen/padding_10"
app:contentPadding="16dp"/>
With the above case, I fixed it this way
<FrameLayout
android:layout_marginTop="16dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ProgressBar
android:id="#+id/progress_reset_password"
android:visibility="visible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateTint="#color/colorAccent"
android:layout_gravity="center_horizontal"
android:translationZ="2dp"
android:elevation="2dp"/>
<Button
android:id="#+id/btnGetOTP"
style="#style/styleButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="80dp"
android:layout_marginRight="80dp"
android:text="#string/check_email"
android:textColor="#color/colorWhite"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</FrameLayout>
Open the image above here
I added overlays to the image view layout using an extra image. Also, put the extra overlay image view just immediately below the main image view.
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="#dimen/spacing_small"
android:layout_marginTop="#dimen/spacing_normal">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/imageViewBlog"
android:layout_width="match_parent"
android:layout_height="#dimen/blog_post_height"
android:scaleType="centerCrop"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_placeholder" />
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/black_overlay" />
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/tvBlogTopTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/spacing_small"
android:ellipsize="end"
android:fontFamily="sans-serif-medium"
android:maxLines="1"
android:textColor="#color/pale_grey"
app:layout_constraintBottom_toTopOf="#+id/tvBlogBigTitle"
app:layout_constraintEnd_toEndOf="#+id/tvBlogBigTitle"
app:layout_constraintStart_toStartOf="#id/tvBlogBigTitle"
tools:text="Travel Inspiration" />
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/tvBlogBigTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/spacing_normal"
android:layout_marginLeft="#dimen/spacing_normal"
android:layout_marginEnd="#dimen/spacing_normal"
android:layout_marginRight="#dimen/spacing_normal"
android:layout_marginBottom="#dimen/spacing_normal"
android:ellipsize="end"
android:maxLines="2"
android:textColor="#color/white"
android:textSize="#dimen/font_tiny"
app:layout_constraintBottom_toBottomOf="#+id/imageViewBlog"
app:layout_constraintEnd_toEndOf="#id/imageViewBlog"
app:layout_constraintStart_toStartOf="#id/imageViewBlog"
tools:text="This Photographer is Selling Prints of Her Wildlife Photos to \n in the Masai Mara…" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
Looks like the below picture.
Overlay image:
There are lots of examples here on how to set z order in xml, which are great. However, if you if you end up needing to programmatically adjust view overlays, and those views happen to be buttons, make sure to set stateListAnimator to null in your xml layout file. stateListAnimator is android's under-the-hood process to adjust translationZ of buttons when they are clicked, so the button that is clicked ends up visible on top. This is not always what you want... for full Z order control, do this:

How to Create Static (Using xml file only) ExpandableListView in Android

I need to insert GroupData and ChildData directly into ExpandableListView in xml file itself without using java. Java file should only for showing xml file not for inserting data.
Our output will be :
Group 1 -> Child 11, Child 12, Child 13
Group 2 -> Child 21, Child 22, Child 23
Group 3 -> Child 31, Child 32, Child 33
Thanks in Advance
I don't think so it is possible . You must have to write code for generating listview using java file.
Look Here for shortest way to generate expandable listview.
If you don't want to use ExpandableListview because of java code to set adapter and all then You can use a cardview which is expand and collapse.
This is the simplest way for static(XML) collapse and expand feature.
<android.support.v7.widget.CardView
android:id="#+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:elevation="3dp"
app:cardCornerRadius="0dp">
<LinearLayout
android:id="#+id/group_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/group_one"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="1"
android:text="Group 1"
android:textStyle="bold" />
<LinearLayout
android:id="#+id/child_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:orientation="vertical">
<TextView
android:id="#+id/child_one"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="1"
android:text="Child 11" />
<TextView
android:id="#+id/child_two"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="1"
android:text="Child 12" />
<TextView
android:id="#+id/child_three"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="1"
android:text="Child 13" />
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
Write the following code in onClickListener
cardView = (CardView) findViewById(R.id.card_view);
childContainer = (LinearLayout) findViewById(R.id.child_container);
boolean flag = false;
cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (flag == true) {
TransitionManager.beginDelayedTransition(cardView);
childContainer.setVisibility(View.GONE);
flag = false;
} else if (flag == false) {
TransitionManager.beginDelayedTransition(cardView);
childContainer.setVisibility(View.VISIBLE);
flag = true;
}
}
});
This is for one group and you can duplicate this code for more groups.

Categories

Resources