I'm having problems with my bottom-sheet because when I open the activity it is on, blocking the view
This happens, I think, because of the XML attribute declaring the bottom-sheet with 350dp of height:
<android.support.v4.widget.NestedScrollView
android:id="#+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="350dp"
android:background="?android:attr/windowBackground"
android:clipToPadding="true"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
The thing is, I can't change that value to 0dp because the next time when I try to open the bottom-sheet, there is no bottom-sheet, because the height is 0dp, so it won't show anything.
My question is, is there a way to declare the bottom-sheet off? (I've tried to setState to STATE_COLLAPSED but didn't work).
Bellow is the java code that interacts with the Bottom Sheet.
JAVA:
View bottomSheet = findViewById( R.id.bottom_sheet );
mBottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
#Override
public void onStateChanged(View bottomSheet, int newState) {
if (newState == BottomSheetBehavior.STATE_COLLAPSED) {
//mBottomSheetBehavior.setPeekHeight(0);
//mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
//mBottomSheetBehavior.isHideable();
}
}
#Override
public void onSlide(View bottomSheet, float slideOffset) {
}
});
first you have to add the attribute
app:behavior_hideable="true"
in your
<android.support.v4.widget.NestedScrollView
android:id="#+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="350dp"
android:background="?android:attr/windowBackground"
android:clipToPadding="true"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
And then you can hide the bottom sheet using
mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN)
and not
mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED)
the state COLLAPSED is between HIDDEN and EXPANDED and his heigth must be specified by the attribute:
app:behavior_peekHeight="200dp"
Write this:
mBottomSheetBehavior.setPeekHeight(0);
In my case i was not able to hide the bottomsheet and it was placed on top of my view. I found out that animateLayoutChanges = "true" in my layout file was causing this issue.
In my case I was using BottomSheetDialog.
app:behavior_hideable - attribute is used to determine if our bottom sheet will hide when it is swiped down. In other words bottom sheet top be off screen, if the peek height isn’t set.
app:behavior_peekHeight - attribute value used to represent how much pixels the bottom sheet will be visible.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/bottom_sheet_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="10dp"
android:orientation="vertical"
android:background="#color/colorPrimaryDerived"
app:layout_behavior="#string/bottom_sheet_behavior"
app:behavior_hideable="true"
app:behavior_peekHeight="0dp"> ........... </LinearLayout>
I set the peekHeight to 50dp. And peek height has nothing to do with the bottomSheet layout height itself which I set 200dp (for example only).
You can view the changes in your XML viewer if the bottom sheet is expanded, if so add the app:behavior_peekHeight = 0dpfrom the xml layout and it will hide and also inform you of the current state.
Inside onCreate add these lines, it can hide the bottombar
mBottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
mBottomSheetBehavior.setHideable(true); //Important to add
mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); //Important to add
When Collapsed set app:behavior_hideable="false"
You need to just simply add the below code and it works perfectly.
To hide the bottomsheet:-
bottomSheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN
To show the bottomsheet:-
bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
You can manually hide that bottom sheet by setting the visibility of the parent linear layout to gone
put this line in your code when you want
if (confirmLayoutBehaviour.getState() != BottomSheetBehavior.STATE_EXPANDED) {
//todo hide your bottom sheet if its already open
confirmLayout.setVisibility(View.GONE);
} else {
//set it to visible if its not open
confirmLayout.setVisibility(View.VISIBLE);
}
it worked for me please try it
Related
I'm trying to make Image buttons act like Radio buttons. Let me explain. I have a basic layout containing an Image Button and a TextView, that I load with different images and texts.
XML layout :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageButton
android:id="#+id/button_category"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="#FFFFFF"/>
<TextView
android:id="#+id/text_category"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
</LinearLayout>
Java method :
LinearLayout categoryLayout = view.findViewById(R.id.categories_layout);
for (int i = 0; i<categories.size(); i++) {
final String name = categories.get(i).name;
final int resource = categories.get(i).resource;
View v = getLayoutInflater().inflate(R.layout.choose_category, null);
final TextView text = v.findViewById(R.id.text_category);
text.setText(name);
ImageButton button = v.findViewById(R.id.button_category);
button.setImageResource(resource);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
selectedCategory = resource;
text.setTypeface(text.getTypeface(), Typeface.BOLD);
}
});
categoryLayout.addView(v);
}
Every time an image is clicked, the text is set bold to indicate which button was clicked. My problem is that I only want one button to be clickable at a time. I thought of, each time a button is clicked, reseting the appearance of all TextView, only leaving the last text that was clicked as bold. However, I don't know how to navigate through all layouts that have been generated.
I hope I was clear, thank you if you can help me !
That might not be the most efficient way to solve this problem, but it works. Every time the button is clicked, the icon selected is saved. Then, I use removeAllViews() method on the RadioGroup, and recreate the views. I just make sure the text below the previously selected icon is set bold.
I have created a note app.
In my app when i create a new note. By default, the cursor is at title edit text but I want to have a feature that if I touch anywhere on the screen the cursor should go to the description edit text. I have kept the description edit text in a separate linear layout which has a weight of 1.
Kindly find the images to get an idea.
In the given picture the area covered with the blue line I want to touch anywhere in that area and my focus should be directed to edit text where I have written the hint description
XML
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/scview"
android:layout_weight="1">
<EditText
android:id="#+id/body_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000"
android:textSize="18sp"
android:inputType="textMultiLine"
android:hint="Description"
android:backgroundTint="#android:color/transparent"/>.
</LinearLayout>
Use onClickListener() on parent layout of your xml like this
RelativeLayout parentRelativelayout=(RelativeLayout)findViewByRid(R.id.your_parent_layout_in_xml);
EditText edtDescription=(Edittext)findViewByRid(R.id.body_content);
parentRelativelayoutsetOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
edtDescription.requestFocus();
}
});
You need to override dispatchTouchEvent method and changes focus , as user touch screen , dispatchTouchEvent method will be fired.
#override Boolean dispatchTouchEvent(MotionEvent ev ) {
Toast.makeText(context ,"dispatchTouchEvent", Toast.LENGTH_SHORT).show()
return super.dispatchTouchEvent(ev)
}
I have created a TextView in XML and have set some rules for it (for example layout_bellow="something"), and made it's height set to 0, so that when a button is clicked, it's height would be set to wrap_content. I wrote the code bellow for the button responsible for resizing, and below it is the XML code i wrote for the TextView. The problem is, when i click the button, the height becomes match_parent, the layout_bellow attribute gets ignored and it is drawn from the start of the parent layout, and width (that was set to match_parent) becomes wrap_content. Whats the problem? thanks.
the Button:
btnExpand.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
textView.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, height));
}
});
the XML:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/firstRow"
android:layout_width="match_parent"
android:layout_height="wrap_content">
.
.
.
</LinearLayout>
<TextView
android:id="#+id/theTextView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_below="#id/firstRow"
android:text="lorem ipsom lorem ipsom">
</RelativeLayout>
EDIT: here's an image to demonstrate the problem
Basically the problem is you are creating new LayoutParams and setting it to the view. You have get the already set(xml) LayoutParams of the view and modify whichever you want to modify and set it back to the View.
LayoutParams layoutParams = textView.getLayoutParams();
//height = LayoutParams.WRAP_CONTENT;or 100 or whatever
layoutParams.height = LayoutParams.WRAP_CONTENT;
textView.setLayoutParams(layoutParams);
I have problem with handling Touch events inside my TextView on Android 2.3.3. I've got Activity implements OnTouchListener with method
main.java
public boolean onTouchEvent(MotionEvent event) {
if(event.getPointerCount()==1){
textView.setTextSize(mRatio+13);
mRatio++;
Log.d("TouchEvent", "one touch !");
}
if (event.getPointerCount() == 2) {
some code...
}
return true;
}
and my layout(only part of it):
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_weight="1.0"
android:fadingEdge="none"
android:background="#color/white">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="10dp">
<!-- TEXT EMAIL : -->
<TextView
android:id="#+id/mail_text"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:textSize="15sp"
android:autoLink="web"
android:clickable="true"
android:textColor="#color/mailtext"
android:scrollbars = "vertical"/>
</LinearLayout>
</LinearLayout>
When i 'clicked' anywhere outside my textBox(for example on header or footer), the Touch event trigger, font get bigger. I assume than the problem is probably because scrollbars. But when I cut off android:scrollbars = "vertical" bar just disappear.
This textView usually contain a lots of text.
How to proper fire onTouchEvents inside this textView.
Edit:
when this textView is small my touchEvent work until i get text so big, than the scrollBar is needed. Then all touch event get overrided and You can only scroll textView. No TouchEvent is called.
I handle the problem in other way. OnTouchEvent didn't worked with my TextView so I Override dispatchTouchEvent. It's far more better to performe actions "onTouch".Scrollbar is working and I can add my multitouch events on the whole screen. It's look like:
#Override
public boolean dispatchTouchEvent(MotionEvent motionEvent){
Log.v("NotificationActivity.dispatchTouchEvent()", "got touch");
if (motionEvent.getPointerCount() == 2) {
Log.v("touch", "multi touch !");
int action = motionEvent.getAction();
int pureaction = action & MotionEvent.ACTION_MASK;
// some actions ...
}
switch (motionEvent.getAction()){
case MotionEvent.ACTION_DOWN:{
//Keep track of the starting down-event.
Log.v("akcjaa","down");
// some actions ...
break;
}
case MotionEvent.ACTION_UP:{
//Consume if necessary and perform the fling / swipe action
//if it has been determined to be a fling / swipe
Log.v("akcjaa","up");
break;
}
}
return super.dispatchTouchEvent(motionEvent);
}
I am assuming your TextView is inside some kind of ScrollView or Scrollable container, right?
Then you will face this issue. Android does not like his apples and pears mixed, you should not be trying to receive "onTouch" events that are being consumed by the father layout on top of the view.
I guess you could:
a) Switch to a onClickListener on your TextView
b) Override your parent view layout touch handler to bleed the touch down to its childs. This is not really 100% recommended, and could cause unwanted behaviour.
Sorry if i cannot be of more help.
I'm building a chat-like application that displays text the user inputs to the screen using a scrollview. What I'd like to do is making the scrollview autoscroll as more text is appended to the screen.
I'm using a textview to display the input. The xml portion of the scrollview is as follows:
<ScrollView
android:id="#+id/scroller"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#id/buttons"
>
<LinearLayout
android:id="#+id/start_chat"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
</LinearLayout>
</ScrollView>
How do I go about doing that? I tried setting the layout's gravity to "bottom", but that doesn't work correctly (text inputed that moves up as the scrollview is scrolled down can't be viewed again).
Any help is greatly appreciated.
If you want to scroll to the absolute bottom (where new TextView is added) use fullScroll on the ScrollView when the TextView is added.
ScrollView my_scrollview = (ScrollView) findViewById(R.id.scroller);
my_scrollview.fullScroll(ScrollView.FOCUS_DOWN);
If instead you want to scroll relative from the current position the user is viewing, I would try something like smoothScrollBy or scrollBy
/* recently_added_textview being the TextView that was added to trigger this */
ScrollView my_scrollview = (ScrollView) findViewById(R.id.scroller);
int height = recently_added_textview.getHeight();
my_scrollview.smoothScrollBy(0, height);
/* x being 0 assuming you don't want to scroll left and right */
This way the user isn't sent to the bottom of the ScrollView if they're reading something around the top or middle.
You can add this after you added a new chat in your textview
scroller.post(new Runnable() {
public void run() {
//ScrollView.FOCUS_DOWN if you want to scroll down
//ScrollView.FOCUS_UP if you want to scroll up
svComments.fullScroll(ScrollView.FOCUS_DOWN);
}
});