slide up bottomsheet by dragging button up(android) - android

I want to control my bottom sheet's state with one button.
The control button is located at the top of the bottom sheet layout.
And if i drag up the control button, bottom sheet will expand.
I tried to search what event triggers bottomsheet's expansion, but couldn't find out.
So my question is, what method in bottomsheetbehavior.class triggers stage change?
enter image description here

You can use this way to change state based on button click
controlBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED){
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
else {
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
});
The callback that gets triggered when your bottomsheet state changes is
bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
#Override
public void onStateChanged(#NonNull View bottomsht, int newstate) {
if (newState == BottomSheetBehavior.STATE_DRAGGING) {
behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
}
#Override
public void onSlide(#NonNull View view, float v) {
}
});

Related

Using a custom BottomSheetDialog class means I can't touchOutside to cancel

So I made a custom class that does basically nothing except boilerplate code plus customizing the callback. For whatever reason, I can't seem to make it cancel when I touch outside the bounds of the bottom sheet.
public class CustomBottomSheetDialog extends AppCompatDialog {
public CustomBottomSheetDialog(Context context) {
super(context, R.style.Theme_Design_Light_BottomSheetDialog);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
}
#Override
public void setContentView(View view) {
final CoordinatorLayout coordinator = (CoordinatorLayout) View.inflate(getContext(),
R.layout.design_bottom_sheet_dialog, null);
FrameLayout bottomSheet = (FrameLayout) coordinator.findViewById(R.id.design_bottom_sheet);
BottomSheetBehavior.from(bottomSheet).setBottomSheetCallback(mBottomSheetCallback);
bottomSheet.addView(view);
super.setContentView(coordinator);
}
private BottomSheetBehavior.BottomSheetCallback mBottomSheetCallback = new BottomSheetBehavior.BottomSheetCallback() {
#Override
public void onStateChanged(View bottomSheet, int newState) {
if (newState == BottomSheetBehavior.STATE_HIDDEN) {
cancel(); // The only not boilerplate code here, woo
}
}
#Override
public void onSlide(View bottomSheet, float slideOffset) { }
};
Things I've tried:
bottomSheetDialog.setCancelable(true);
bottomSheetDialog.setCanceledOnTouchOutside(true);
Overriding dispatchTouchEvent, but I can't get the rectangle to equal anything besides the size of the entire screen.
If I don't use the custom class (ie simply change my CustomBottomSheetDialog call to just BottomSheetDialog), I get the cancel on touch outside, but then I don't get a cancel when I drag to hide the dialog, which I am required to have.
Finally got it. In the onCreate, I added a single line of code to find the touch_outside view and add a click listener to cancel the dialog. The touch_outside view is generated by default. I did not need to add it in my bottom sheet's XML.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
findViewById(R.id.touch_outside).setOnClickListener(v -> cancel()); // <--- this guy
getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
}
Thanks goes to this tutorial.

how to disable the SwipeMenuLIstView to Swipe based on position?

i am using Swipe menu list View from the Github
https://github.com/baoyongzhang/SwipeMenuListView
According to my project requirement i need to stop list View to Swipe based on position.
For example i want to stop the list item to swipe on the position 2
how would i do that?
mListView.setOnSwipeListener(new SwipeMenuListView.OnSwipeListener() {
#Override
public void onSwipeStart(int position) {
if (positon == 2) {
Toast.makeText(getApplicationContext(), "you are not Allow to Swipe", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onSwipeEnd(int position) {
}
});

CardView responding to click events even when hidden

I have a form with a clickeable cardview. Depending on some of the options, I hide the CardView setting its visibility to GONE.
Other form controls below the card come up to occupy the space the cardview was taking. However when clicking in the area the Cardview used to be, the onclick event is fired for the cardview.
I even put a check to verify the visibility before the click action, but the cardview repots VISIBLE (even though its not being shown). I use Butterknife for the onClick event:
#OnClick(R.id.logo_cardview)
public void onLogoClick(){
if (mLogoCardView.getVisibility() == VISIBLE) {
Snackbar.make(this, "Logo clicked", Snackbar.LENGTH_SHORT).show();
showSettingsDialog();
}
}
I hide the Cardview using an animation:
mAlphaAnimation = new AlphaAnimation(1.0f, 0.0f);
mAlphaAnimation.setDuration(200);
mAlphaAnimation.setFillAfter(true);
mHideListener = new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
mMatchInfo.setVisibility(View.GONE);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
};

Catch dismissal of BottomSheetDialogFragment

Is there any way to catch the dismissal/cancel of a BottomSheetDialogFragment?
Bottom sheet class
public class ContactDetailFragment extends BottomSheetDialogFragment
{
private BottomSheetBehavior.BottomSheetCallback mBottomSheetBehaviorCallback = new BottomSheetBehavior.BottomSheetCallback()
{
#Override
public void onStateChanged(#NonNull View bottomSheet, int newState)
{
if (newState == BottomSheetBehavior.STATE_HIDDEN)
{
dismiss();
}
}
#Override
public void onSlide(#NonNull View bottomSheet, float slideOffset)
{
}
};
#Override
public void setupDialog(Dialog dialog, int style)
{
super.setupDialog(dialog, style);
View contentView = View.inflate(getContext(), R.layout.fragment_contactdetail, null);
dialog.setContentView(contentView);
BottomSheetBehavior mBottomSheetBehavior = BottomSheetBehavior.from(((View) contentView.getParent()));
if (mBottomSheetBehavior != null)
{
mBottomSheetBehavior.setBottomSheetCallback(mBottomSheetBehaviorCallback);
mBottomSheetBehavior.setPeekHeight((int) DisplayUtils.dpToPixels(CONTACT_DETAIL_PEEK_HEIGHT, getResources().getDisplayMetrics()));
}
}
}
What I've tried that doesn't work
in setupDialog adding either of dialog.setOnCancelListener(); or dialog.setOnDismissListener(); never gets triggered
the bottomsheet behavior's onStateChanged only gets triggered if the user drags the bottomsheet down passed the collapsed state, and there is no state for dismissed/cancelled
adding the same oncancel/ondismiss listeners to the instantiation of the BottomSheetDialogFragment, by using ContactDetailFragment.getDialog().setOnCancelListener() does not get triggered
Given that it's essentially a dialog fragment, there must be some way to catch the dismissal?
Found a simple solution.
Using onDestroy or onDetach in the BottomSheetDialogFragment allows me to get the dismissal correctly

Override design support library behaviour

I am trying to dismiss a Snackbar when a condition is satisfied.
snackbar.setAction("Retry", new View.OnClickListener() {
#Override
public void onClick(View view) {
if(isConnected(getApplicationContext())){
toggleButtonsState(true);
snackbar.dismiss();
} else {
snackbar.show();
}
}
});
snackbar.show();
However, the Snackbar implementation do automatic dismiss of it when the action is clicked.
public Snackbar setAction(CharSequence text, final OnClickListener listener) {
TextView tv = this.mView.getActionView();
if(!TextUtils.isEmpty(text) && listener != null) {
tv.setVisibility(0);
tv.setText(text);
tv.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
listener.onClick(view);
Snackbar.this.dismiss();
}
});
} else {
tv.setVisibility(8);
tv.setOnClickListener((OnClickListener)null);
}
return this;
}
Generally, is there a way to modify a compiled gradle library so as to cope with my needs. ie. to remove this line Snackbar.this.dismiss();. I know I can search for the source and put in in libs folder and then I can modify it but is there a way to do so rather than this?
Unfortunately, you can't because Snackbar class is final and cannot override methods so it's behavior.
What you can try, is setting View.OnTouchListener to Snackbar view and prevent it getting any touch events only for the action view. I'm not sure if snackBar.getView() returns whole snackbar including the action views.
snackBar.getView().setOnTouchListener(new View.OnTouchListener(){
#Override
public boolean onTouch (View v, MotionEvent event){
if(v instanceof Button) {
//This is the Action view event, do your logic.
if(isConnected(getApplicationContext())){
toggleButtonsState(true);
return false;
}
return true;
}
//not action view, proceed normally
return false;
});

Categories

Resources