ViewGroup (LinearLayout) and Child onClick event not passed to ViewGroup - android

I have a LinearLayout with several seekbars as childs, on the SeekBars i use the android:clickable=false and on the LinearLayout i have the android:clickable=trueand the corresponding setOnClickListenner defined however any press on the the SeekBars doesn't trigger the LinearLayout click, i have read somewhere that it should and tested it by replacing the SeekBars with Buttons and setting the clickable property to false and the click is bubbled up to the parent.
My question is why the behaviour is not similar ?
Edit: Added code example
Layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MyActivity">
<LinearLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:longClickable="false"
android:focusable="false"
/>
<Button
android:layout_marginTop="10dp"
android:clickable="false"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Click me!"/>
</LinearLayout>
Activity:
public class MyActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
ViewGroup container = (ViewGroup) findViewById(R.id.container);
container.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(MyActivity.this, "Container was clicked", Toast.LENGTH_SHORT).show();
}
});
}
}

Having finally understood what you are asking I think this will fix it. The SeekBar is not focusable and the Button is.
This is the reason it will not work for you delete this line from the SeekBar:
android:focusable="false"
Allowing this to be focusable should make both the Button and SeekBar function the same way when they are clicked.

Related

Showing Toast in fragments

I want to show toast on button click, and that button is in the fragment. I have tried methods to get context for the toast, but it is not showing on button click.
This is my code
public class Bottom_Sheet_Fragment extends Fragment {
Button addComment;
public Bottom_Sheet_Fragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment_bottom__sheet, container, false);
addComment=(Button) container.findViewById(R.id.addCommentBtn);
addComment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getActivity(), "Added", Toast.LENGTH_SHORT).show();
}
});
return view;
}
}
This is fragment layout
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/bottom_sheet1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/holo_blue_light"
android:fillViewport="true"
android:orientation="vertical"
app:behavior_hideable="true"
app:behavior_peekHeight="0dp"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/holo_blue_light"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/commentList"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="#+id/etComment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:hint="Write comment" />
<Button
android:id="#+id/addCommentBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:text="Add" />
</RelativeLayout>
</LinearLayout>
this layout file is included in another activity, with in include statement.dont know where is the problem. and this fragment works like a bottomsheet.
Try this: addComment = view.findViewById(R.id.addCommentBtn);
Because you must get button from layout was inflated.
You need to use view.findViewById.
Try This
addComment=(Button) view.findViewById(R.id.addCommentBtn);
addComment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getActivity(), "Added", Toast.LENGTH_SHORT).show();
}
});

Android: fitsSystemWindows and newline interfering with bottomSheets

I have found out that if the parent layout contains android:fitsSystemWindows="true", it will interfere with my BottomSheets positioning, when a view-related action happens.
Specifically the one I'm encountering: where a newline in a textview will trigger the bottomsheets to offset by the height of the system/notif-bar.
newline + fitsSystemWindows = shoves my bottomsheet down
I eliminated all irrelevant stuff down to buttons, textview and the bottomsheet.
Button2: setText("1\n2") is where the magic happens
As soon as I remove android:fitsSystemWindows="true", it's all ok, no more strange behavior, but I lose the effect of how fitsSystemWindows colors in the system/notif-bar.
I also tried to give my bottomSheet layout its own android:fitsSystemWindows="false", but it has had no effect.
How can I achieve both fitsSystemWindows=true without this strange offset behavior on my bottomSheets?
See for yourself!
public class Test extends AppCompatActivity {
private BottomSheetBehavior bottomSheetBehavior;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_test);
LinearLayout bottomSheet = (LinearLayout) findViewById(R.id.root_btmsheet);
bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
bottomSheet.post(new Runnable() {
#Override
public void run() {
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
});
((Button) findViewById(R.id.btn1)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
((TextView) findViewById(R.id.info1)).setText("1");
}
});
((Button) findViewById(R.id.btn2)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// the culprit, Mr. Newline
((TextView) findViewById(R.id.info1)).setText("1\n2");
}
});
}
}
act_test.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true" <-- the other culprit, Ms. Fits
tools:context=".Test">
<!--<include layout="#layout/act_test_content" />-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:orientation="vertical"
android:id="#+id/root_content">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="#+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1" />
<Button
android:id="#+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2" />
</LinearLayout>
<TextView
android:id="#+id/info1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#e0e0e0" />
</LinearLayout>
<!--<include layout="#layout/act_test_btmsheet" />-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="200dp"
app:layout_behavior="#string/bottom_sheet_behavior"
android:orientation="vertical"
app:behavior_hideable="false"
app:behavior_peekHeight="50dp"
android:background="#5533b5e5"
android:id="#+id/root_btmsheet">
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
I too had a similar problem even with support library 25.1.0. But I later figured out that it could have been because of not using a CollapsingToolbarLayout. I included it and bang!.. it is behaving normally even after any layout changes due to linebreaks

Linear Layout onclick listener not working with recycle view

I have a problem with Recycleview in linearLayout. In the below code When I click on chat section(Linear Layout) Toast is not getting visible when I set LayoutManager to RecycleView. Please help me the toast will be visible when I click on linear layout.
Activity code:
public class PracticeActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_practice);
setLayoutViews();
}
private void setLayoutViews(){
// setting up messages list view
RecyclerView mMessagesView = (RecyclerView) findViewById(R.id.messages);
// if i uncomment below line Toast will not be visible.
//mMessagesView.setLayoutManager(new LinearLayoutManager(this));
(findViewById(R.id.chat_section)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(PracticeActivity.this, " Chat section was clicked", Toast.LENGTH_SHORT).show();
}
});
}
activity_practice.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/activity_main">
<LinearLayout
android:id="#+id/chat_section"
android:layout_width="match_parent"
android:layout_height="320dp"
android:background="#color/chat_back_ground">
<android.support.v7.widget.RecyclerView
android:id="#+id/messages"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:scrollbars="vertical"
android:scrollbarStyle="outsideOverlay"/>
</LinearLayout>
<TextView
android:layout_below="#id/chat_section"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Just text"/>
</RelativeLayout>
You can follow this tutorial. The process followed is to create a separate itemtouchlistener class from which the selection is identified
http://sapandiwakar.in/recycler-view-item-click-handler/

Layout not moving when its inside to SwipeRefreshLayout in android?

I working with SwipeRefreshLayout. Here what my need is...
Im using one Linearlayout inside SwipeRefreshLayout which is in "RED COLOR".
when im trying to pull down that layout, that layout is not moving. Only its showing that refresh circular arrow, But i want to pull down that whole "Red color" layout. How to achieve this?
Please find my sources for reference.
Suggestion please....
mylayout.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="#000000">
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipeRefreshLayout_emptyView"
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="#ff0000"
>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sample SwipeRefreshLayout"
android:layout_marginTop="50dp"
android:textColor="#ffffff" />
</LinearLayout>
</ScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
MyClass.java
public class MyClass extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
private SwipeRefreshLayout swipeLayout;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.mylayout,null);
swipeLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipeRefreshLayout_emptyView);
onCreateSwipeToRefresh(swipeLayout);
return view;
}
private void onCreateSwipeToRefresh(SwipeRefreshLayout swipeLayout) {
swipeLayout.setOnRefreshListener(this);
swipeLayout.setColorSchemeColors(android.R.color.holo_green_dark, android.R.color.holo_red_dark,
android.R.color.holo_blue_dark, android.R.color.holo_orange_dark);
}
#Override
public void onRefresh() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Used PullRefreshLayout instead SwipeRefreshLayout from this sample
Instead for using a ScrollView as child of SwipeRefreshLayout, try using a RelativeLayout / LinearLayout and make the ScrollView a child of it.
something like this:
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipeRefreshLayout_emptyView"
android:layout_width="match_parent"
android:layout_height="300dp"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff0000">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
//Leave the interior the same
</ScrollView>
</LinearLayout>
</android.support.v4.widget.SwipeRefreshLayout>
Also apply the red color to your LinearLayout. You currently have it in your SwipeRefreshLayout
Your ScrollView should not wrap_content on its height but match_parent

Specify where ListFragment goes in activity_main.xml

My activity_main.xml is evenly split vertically 3 ways with LinearLayout. I would like to fill the bottom LinearLayout with a ListFragment and populate it with data.
Currently, the ListFragment ignores the 3 LinearLayout and just places itself on top of them.
LstFragment.java
public class LstFragment extends ListFragment{
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragmentlayout, container, false);
// Create an array of string to be data source of the ListFragment
String[] datasource={"English","French","Khmer","Japanese","Russian","Chinese"};
// Create ArrayAdapter object to wrap the data source
ArrayAdapter<String> adapter=new ArrayAdapter<String>(getActivity(),R.layout.rowlayout,R.id.txtitem,datasource);
// Bind adapter to the ListFragment
setListAdapter(adapter);
// Retain the ListFragment instance across Activity re-creation
setRetainInstance(true);
return rootView;
}
// Handle Item click event
public void onListItemClick(ListView l, View view, int position, long id){
ViewGroup viewg=(ViewGroup)view;
TextView tv=(TextView)viewg.findViewById(R.id.txtitem);
Toast.makeText(getActivity(), tv.getText().toString(),Toast.LENGTH_LONG).show();
}
}
MainActivity.java
public class MainActivity extends FragmentActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LstFragment lstfragment=(LstFragment)getSupportFragmentManager().findFragmentByTag("lstfragment");
if(lstfragment==null){
lstfragment=new LstFragment();
FragmentTransaction transact=getSupportFragmentManager().beginTransaction();
transact.add(android.R.id.content,lstfragment,"lstfragment");
transact.commit();
}
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:id="#+id/topSection">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Testing"
android:id="#+id/textView3" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:id="#+id/middleSection">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Yo"
android:id="#+id/textView2"
android:layout_gravity="center_horizontal" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:id="#+id/bottomSection">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="WhatUP"
android:id="#+id/textView"
android:layout_gravity="center_horizontal" />
</LinearLayout>
</LinearLayout>
There are two more simple .xml layout files called fragmentlayout.xml which contains a simple ListView #id/android:list and a rowlayout.xml which has a single TextView #id/textitem.
Replace
android:layout_height="fill_parent"
with this line
android:layout_height="0dp"
inside all the three child linear layouts
Reason
android.R.id.content gives you the root element of a view, without having to know its actual name/type/ID. That's why your Fragment is appearing at the top of everything.
You are trying to add your Fragment to wrong container here
transact.add(android.R.id.content,lstfragment,"lstfragment");
Solution
Add this
<FrameLayout
android:layout_width="fill_parent"
android:id="#+id/fragment_container"
android:layout_height="fill_parent">
</FrameLayout>
after 3rd LinearLayout but before closing the root LinerarLayout
then change to
transact.add(R.id.fragment_container,lstfragment,"lstfragment");
Also,
in all of the LinearLayout use this android:layout_height="wrap_content"

Categories

Resources