OnClickListener Layout detection - android

I've a custom button layout: Its a FrameLayout as a background with a normal Button in the center with an icon next to the text.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/framelayout"
style="?android:attr/buttonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:background="#F00">
<android.support.v7.widget.AppCompatButton
android:id="#+id/buttonWithIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
android:background="#null"
android:drawableStart="#android:drawable/ic_delete"
android:gravity="center"
android:textAllCaps="false"
android:textColor="#FFF"/>
</FrameLayout>
I had an onClickListeners on the Button and I realized, clicks on the background (=FrameLayout) weren't detected. Because of this I want an onClickListener that detects clicks on the FrameLayout and also on the Button, without having two Listeners, that do the same.
I tried giving the RelativeLayout an ID, but the layout couldn't be found (=null).
Maybe my button layout isn't optimal. But I need a fullwidth button with a icon next to the text, without any spaces between the icon and the text.
The Icons gets set like this
button.setCompoundDrawablesWithIntrinsicBounds(R.mipmap.ic_icon, 0, 0,0);
Thank you

You can just add one OnClickListener to both views. That way, you only write your code once, and if you click either the FrameLayout or the Button that same code will run.
final View.OnClickListener mOnClickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Add Your OnClick Code Here
}
};
framelayout.setOnClickListener(mOnClickListener);
buttonWithIcon.setOnClickListener(mOnClickListener);

You can put all of your views that you want them to be clickable and remove all clickListeners of entire views.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/linearlayout">
<FrameLayout
style="?android:attr/buttonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:background="#F00">
<android.support.v7.widget.AppCompatButton
android:id="#+id/buttonWithIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
android:background="#null"
android:drawableStart="#android:drawable/ic_delete"
android:gravity="center"
android:textAllCaps="false"
android:textColor="#FFF"/>
</FrameLayout>
</LinearLayout>
and add this clickListener to LinearLayout:
LinearLayout linearlayout=(linearLayout)findViewById(R.id.linearlayout);
linearlayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Add Your Code Here
}
});

Create a function in your Activity with a View Argument, and in your layout, set the onClick to your two views.
Activity:
public void myAction(View v){
// Do what you want
}
Your Layout:
<FrameLayout
android:id="#+id/framelayout"
style="?android:attr/buttonStyle"
android:onClick="myAction"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:background="#F00">
<android.support.v7.widget.AppCompatButton
android:id="#+id/buttonWithIcon"
android:onClick="myAction"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
android:background="#null"
android:drawableStart="#android:drawable/ic_delete"
android:gravity="center"
android:textAllCaps="false"
android:textColor="#FFF"/>
</FrameLayout>
Maybe adding in just the FrameLayout may dispatch the event in the button also, i can't test right now :)

Related

How to call a layout inside the linear layout after clicking the buttons?

I'm learning android and And I'm facing some troubles. I kindly request you to solve these problems.
I have 2 linear layouts inside a linear layout, both are placed horizontally. The left side section contains some buttons and if we click the button the respective layout must come on the right-side section. As of now, if I click the button the specific layout is appearing but not inside the second linear layout. And also, I want to set a default layout to appear on the right side layout. For ex, here I've added the "breakfastdishes.xml", which I want as a default right-side layout, and when I click on the buttons from the left-side layout, according to id the right-side layout must change. Can you please help me to achieve it?
Here is my code:
MenuSection.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
tools:context=".MenuSection"
android:background="#drawable/gradient"
android:padding="10dp">
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:id="#+id/breakfast"
android:layout_width="220dp"
android:layout_height="65dp"
android:text="#string/breakfast"
android:textSize="20dp"
android:background="#drawable/menu_category"
android:fontFamily="sans-serif"
android:textStyle="bold"
app:backgroundTint="#AC8E0D"/>
<Button
android:id="#+id/lunch"
android:layout_width="220dp"
android:layout_height="65dp"
android:layout_marginTop="60dp"
android:text="#string/lunch"
android:textSize="20dp"
android:background="#drawable/menu_category"
android:fontFamily="sans-serif"
android:textStyle="bold"
app:backgroundTint="#0A5FAA"/>
<Button
android:id="#+id/eveningSnacks"
android:layout_width="220dp"
android:layout_height="65dp"
android:layout_marginTop="60dp"
android:background="#drawable/menu_category"
android:fontFamily="sans-serif"
android:text="#string/snacks"
android:textSize="20dp"
android:textStyle="bold"
app:backgroundTint="#DF5124" />
<Button
android:id="#+id/dinner"
android:layout_width="220dp"
android:layout_height="65dp"
android:layout_marginTop="60dp"
android:text="#string/dinner"
android:textSize="20dp"
android:background="#drawable/menu_category"
android:fontFamily="sans-serif"
android:textStyle="bold"
app:backgroundTint="#14A61A"/>
</LinearLayout>
</ScrollView>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:id="#+id/itemsDisplay">
<LinearLayout
android:id="#+id/menuDispArea"
android:layout_width="508dp"
android:layout_height="412dp">
<!-- <include-->
<!-- layout="#layout/breakfastdishes"-->
<!-- android:layout_width="508dp"-->
<!-- android:layout_height="412dp" />-->
</LinearLayout>
</ScrollView>
</LinearLayout>
BreakfastDishes.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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_height="match_parent"
android:background="#drawable/gradient"
android:paddingStart="12dp"
android:paddingLeft="10dp"
android:paddingTop="20dp"
android:paddingEnd="12dp"
android:paddingRight="10dp"
android:paddingBottom="20dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:orientation="vertical">
<ImageView
android:id="#+id/burger"
android:layout_width="155dp"
android:layout_height="102dp"
android:layout_x="10dp"
android:layout_y="10dp"
app:srcCompat="#mipmap/burger_breakfast" />
<TextView
android:id="#+id/burgerTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/burger"
android:layout_alignTop="#+id/burger"
android:layout_alignRight="#+id/burger"
android:layout_alignBottom="#+id/burger"
android:layout_gravity="center_horizontal"
android:layout_margin="1dp"
android:gravity="center"
android:text="#string/burger"
android:textColor="#FFF"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:orientation="vertical">
<ImageView
android:id="#+id/eggOmlet"
android:layout_width="160dp"
android:layout_height="104dp"
android:layout_x="233dp"
android:layout_y="7dp"
app:srcCompat="#mipmap/egg_omlet" />
<TextView
android:id="#+id/eggOmletTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/eggOmlet"
android:layout_alignTop="#+id/eggOmlet"
android:layout_alignRight="#+id/eggOmlet"
android:layout_alignBottom="#+id/eggOmlet"
android:layout_gravity="center_horizontal"
android:layout_margin="1dp"
android:gravity="center"
android:text="#string/eggOmlet"
android:textColor="#FFF"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
MenuSection.java
package com.example.restaurant;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MenuSection extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu_section);
Button breakfast = (Button) findViewById(R.id.breakfast);
Button lunch = (Button) findViewById(R.id.lunch);
breakfast.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MenuSection.this, BreakfastDishes.class);
startActivity(intent);
}
});
lunch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MenuSection.this, LunchDishes.class);
startActivity(intent);
}
});
}
#Override
public void onBackPressed(){
//super.onBackPressed();
}
}
Akshay, here are a few things you have to keep in mind ;
In the button click listener you are launching new activity instead of updating
the existing layout. When you use Intent it will launch new activity and
close the current activity. So in your case do not use startActivity
Use findViewById for the menuDispArea layout and add update
the content when user clicks on the button.
never use dp for text size, use sp
you can divide the layout using LinearLayout weights to split your layouts on
all the devices instead of hardcoding the height and width
https://developer.android.com/guide/topics/ui/layout/linear#Weight
edit: Added sample
LayoutInflater inflater = LayoutInflater.from(MenuSection.this);
LinearLayout parentLayout = findViewById(R.id.menuDispArea);
View menuLayout= inflater.inflate(R.layout.BreakfastDishes, parentLayout, false);
parentLayout.addView(menuLayout);
You can use this to inflate any XML in your layout dynamically. Make sure you are doing this inside button onClick for your use case.

How can i detect if a Card or a RecyclerView's item is selected?

i'm new to Android and i'm working on a University project, an app to take notes. I can add and delete note, but i would like to implement a classic way to delete an item: long press on it and delete it with dialogs or whatever.
This is what i have: Main Activity
I tried to click for a few seconds on the cards/notes (they are in a recycle view nested in a coordinator layout) and i saw that a background visual effect is displayed, so i think that something is already implemented.
Let me know if you need XML layout implementation or something else to answer. Thanks! :)
EDIT
requested code
CardView cardView = findViewById(R.id.cardId);
cardView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
Toast.makeText(MainActivity.this, "long click!", Toast.LENGTH_SHORT).show();
return true;
}
});
XML Declaration of the cardview
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/touch_layout"
android:background="?attr/selectableItemBackground">
<androidx.cardview.widget.CardView
android:id="#+id/cardId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="#style/cardStyle"
android:elevation="4dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginBottom="4dp"
android:layout_marginTop="4dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp">
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
tools:text="title"
android:textStyle="bold"
android:textSize="20sp"
android:layout_toStartOf="#id/showText"/>
<androidx.appcompat.widget.AppCompatImageButton
android:id="#+id/showText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:src="#drawable/ic_leftarrow" />
<TextView
android:id="#+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/text"
android:layout_alignParentEnd="true"
android:textSize="12sp"
android:layout_marginTop="4dp"
tools:text="#string/date" />
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_marginTop="10dp"
android:layout_below="#+id/title"
tools:text="message..." />
</RelativeLayout>
</androidx.cardview.widget.CardView>
</RelativeLayout>
You can use long click listener easy on recylerview
itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
Log.v("LongClick: "+"LongClick");
return true;// returning true instead of false, works for me
}
});
What you see in the background is the nativen effect applied on some ItemViews by Android. For registering clicks, follow these steps:
Create the layout in the XML and assign an ID to it.
<TextView
android:id="#+id/timestamp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:layout_marginBottom="2dp"
android:layout_marginRight="16dp"
android:layout_alignParentEnd="true"/>
Declare and define the view (TextView in this case) by using the assigned ID:
TextView messageText;
messageText = itemView.findViewById(R.id.timestamp);
Attach Listener to register clicks:
messageText.setOnLongClickListener(new View.OnClickListener() {
#Override
public void onLongClick(View view){
// Do what you want here.
}
});

Android frame layout click listener not working

I've got a FrameLayout with two nested LinearLayouts. I want an onClickListener() for FrameLayout. After a search I got a solution clickable="false".
This is my Layout file:
<FrameLayout
android:id="#+id/flOuter"
android:paddingLeft="#dimen/half_margin"
android:paddingRight="#dimen/half_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:clickable="false"
android:gravity="center"
android:id="#+id/flAddIdProof"
android:background="#drawable/add_background"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:clickable="false"
android:id="#+id/ivIcon"
android:src="#drawable/ic_add_black_48dp"
android:background="#drawable/add_button_border"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:clickable="false"
android:id="#+id/llLinear"
android:alpha="0.5"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:enabled="false"
android:clickable="false"
android:drawablePadding="#dimen/half_margin"
android:drawableLeft="#drawable/ic_devices_black_24dp"
android:hint="Identity Proof"
android:inputType="none"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<EditText
android:enabled="false"
android:clickable="false"
android:drawableLeft="#drawable/ic_border_color_black_24dp"
android:hint="Identity Number"
android:drawablePadding="#dimen/half_margin"
android:inputType="none"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</FrameLayout>
Here is my click listener:
flOuter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(DeviceInMeeting.this, "detect", Toast.LENGTH_SHORT).show();
}
});
I don't know how to debug for onClick listeners, clickable="false" is not working in my case.
Try implementing android:clickable="true" in Following code snippet for FrameLayout
<FrameLayout
android:id="#+id/flOuter"
android:clickable="true"
android:focusable="true"
android:foreground="attr/selectableItemBackground"
android:paddingLeft="#dimen/half_margin"
android:paddingRight="#dimen/half_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content">
and adding android:clickable="false" in other nested layout.
<LinearLayout
android:id="#+id/flOuter"
android:clickable="false" />
You are using it wrong. Try using:
<FrameLayout
android:id="#+id/flOuter"
android:paddingLeft="#dimen/half_margin"
android:paddingRight="#dimen/half_margin"
android:layout_width="match_parent"
android:clickable="true"
android:layout_height="wrap_content">
// Other layouts there
</FrameLayout>
For fields you don't want to be clicked add clickable=false to them.
And for fields for which you wan't click event add clickable=true for them.
One thing to remember here is that if your child elements contain some clickable elements like buttons and edittexts and then you want to get click event on parent layout then add clickable false to the child and true to the parent.
You need to set OnTouchListener instead onClickListener. In onTouch method you can decide if touch event is pass to children (by returning false) or consume event.
On your case you should do your logic and return true.

Unable to programmatically scroll to top of ScrollView or SetFocus

I have a ScrollView with a nested LinearLayout that has some length to it. At the bottom I have a button that has a function that will need to act similarly to a Return to Top.
I've tried creating an onClickListener and with setFocusableInTouchMode and setFocusable set to true, use the listener to request focus. No luck.
I've tried the following without success.
scrollView.smoothScrollTo(0,0);
scrollView.fullScroll(scrollView.FOCUS_UP);
scrollGetStartedGetMostFromLearning.fullScroll(View.FOCUS_UP);
XML
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Title"
android:id="#+id/textgTitle"
android:textColor="#F0F0F0"
android:textSize="30sp"
android:focusable="true"
android:focusableInTouchMode="true"/>
<Button
android:id="#+id/btnTop"
android:text="To Top"
android:textSize="25sp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/white"
/>
</LinearLayout>
</ScrollView>
Java
btnTop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
scrollView.fullScroll(View.FOCUS_UP);
} //or any of the 3 used above
Any help or direction as to what I'm doing wrong is appreciated. Thanks!

View Gone when clicked outside that view

I wanted to hide the view when clicking outside that view, for example,
<Framelayout android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="#+id/imgButtonToOpenGrid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|bottom"
android:src="#drawable/open_grid_img"
/>
<RelativeLayout
android:id="#+id/containerGrid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|bottom"
>
<Button
android:id="#+id/button1grid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/favourites"
/>
<Button
android:id="#+id/button2grid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/recent"
android:layout_toRightOf="#+id/button1grid"
/>
<Button
android:id="#+id/button3grid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/gridview"
android:layout_toRightOf="#+id/button2grid"
/>
</RelativeLayout>
</FrameLayout>
What I am doing in my app is oncreate i am hiding the RelativeLayout view with id="containerGrid" and making that relativeLayout view visible when I click on the imageview.
So my requirement is I wanted to hide the container RelativeLayout with id="containerGrid" when I click outside that container.
I tried to get the framelayout container and when clicked on that container checking if relativelayout container is shown or not , if shown then made its view gone. Here is the code i tried,
containerMap = (FrameLayout)findViewById(R.id.container);
containerMap.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// TODO Auto-generated method stub
if(rltvContainer.isShown()){
rltvContainer.setVisibility(View.GONE);
}
}
});
Is there anywhere i am going wrong in above thing.
Actually i have map too in that framelayout container so here i am expecting when i click on a map the relativelayout container should go.
Add another coverView which is transparent in front of the map fragment
<Framelayout android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<View
android:id="#+id/coverView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:background="#00000000"
android:visibility="gone"
/>
<ImageView
android:id="#+id/imgButtonToOpenGrid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|bottom"
android:src="#drawable/open_grid_img"
/>
<RelativeLayout
android:id="#+id/containerGrid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|bottom"
>
<Button
android:id="#+id/button1grid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/favourites"
/>
<Button
android:id="#+id/button2grid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/recent"
android:layout_toRightOf="#+id/button1grid"
/>
<Button
android:id="#+id/button3grid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/gridview"
android:layout_toRightOf="#+id/button2grid"
/>
</RelativeLayout>
</FrameLayout>
When the containerGrid is opened(which means its' visibility is View.VISIBLE, set the coverView's visibility to View.VISIBLE.
If you want to close containerGrid, which is that you want to click outside containerGrid, you actually click on the coverView, set OnClickListener to the coverView:
coverView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// TODO Auto-generated method stub
if(rltvContainer.isShown()){
rltvContainer.setVisibility(View.GONE);
}
coverView.setVisibility(View.Gone);
}
});
set both coverView and containerGrid to View.GONE.
Try setting dependent focusability false in framelayout and it will work
The problem is frame layout is not getting the click event
Descendent focus ability false give you ability disable click event in child views if a parent vieegroup

Categories

Resources