I have created a DrawerLayout with a right side drawer. So far, so good. Now, there's one menu item which, when clicked opens a pop-out menu with 5 different options (see screenshot). When one of the options is clicked the icon in the main menu should get swapped for the icon that I just clicked and then the main menu should close. However, I have not been able to create that behaviour. Currently when I try to click one of the options in the pop-out menu the following happens:
1. The main menu (the drawer) closes.
2. Only if I click the desired option again the icon in the main menu gets swapped.
As far as I understand this it is the default behaviour of a drawer within a DrawerView to be closed as soon as I click somewhere in the screen. I have tried to work around it by setting the lock mode:
myDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN, Gravity.END)
... but no luck. The drawer closes as soon as I try to click one of the items in the pop-out.
Is it even possible to achieve what I want in a DrawerLayout?
Here's my code:
activity_main.xml
<android.support.v4.widget.DrawerLayout
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:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="net.videosc2.activities.VideOSCMainActivity">
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/camera_preview"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:id="#+id/camera_downscaled"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:antialias="false"
android:contentDescription="#string/preview_image_content_description"
android:scaleType="fitXY"/>
</FrameLayout>
<!-- The navigation drawer that comes from the right (layout_gravity:end) -->
<ListView
android:id="#+id/drawer"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_gravity="center_vertical|end"
android:background="#99000000"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="10dp"
app:itemTextColor="#android:color/white"/>
</android.support.v4.widget.DrawerLayout>
drawer_item.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/tool"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/activatedBackgroundIndicator"
android:contentDescription="#string/a_tools_menu_item"
android:gravity="center_vertical"
android:paddingBottom="8dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:paddingTop="8dp"/>
color_mode_panel.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/color_mode_panel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginEnd="60dp"
android:layout_marginRight="60dp"
android:layout_marginTop="100dp"
android:background="#99000000"
android:clickable="true"
android:orientation="horizontal">
<ImageButton
android:id="#+id/mode_rgb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:contentDescription="#string/color_mode_rgb"
android:padding="8dp"
android:src="#drawable/rgb"/>
<ImageButton
android:id="#+id/mode_rgb_inv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:clickable="true"
android:contentDescription="#string/color_mode_rgb_neg"
android:padding="8dp"
android:src="#drawable/rgb_inv"/>
<ImageButton
android:id="#+id/mode_r"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:contentDescription="#string/color_mode_r"
android:padding="8dp"
android:src="#drawable/r"/>
<ImageButton
android:id="#+id/mode_g"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:contentDescription="#string/color_mode_g"
android:padding="8dp"
android:src="#drawable/g"/>
<ImageButton
android:id="#+id/mode_b"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:contentDescription="#string/color_mode_b"
android:padding="8dp"
android:src="#drawable/b"/>
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
static final String TAG = "MainActivity";
View camView;
public static Point dimensions;
private DrawerLayout toolsDrawerLayout;
private FrameLayout mainFrame;
private ActionBarDrawerToggle drawerToggle;
protected ArrayList<View> uiElements = new ArrayList<>();
// is device currently sending OSC?
public boolean isPlaying = false;
// is flashlight on?
public boolean isTorchOn = false;
// don't create more than one color mode panel
private boolean isColorModePanelOpen = false;
public Fragment cameraPreview;
Camera camera;
/**
* Fragment managing the behaviors, interactions and presentation of the navigation drawer.
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
final FragmentManager fragmentManager = getFragmentManager();
if (findViewById(R.id.camera_preview) != null) {
camView = findViewById(R.id.camera_preview);
if (savedInstanceState != null) return;
cameraPreview = new VideOSCCameraFragment();
fragmentManager.beginTransaction()
.replace(R.id.camera_preview, cameraPreview, "CamPreview")
.commit();
}
TypedArray tools = getResources().obtainTypedArray(drawer_icons_id);
toolsDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
toolsDrawerLayout.setScrimColor(Color.TRANSPARENT);
// FIXME: touches seem to get swallowed by the DrawerLayout first
final ListView toolsDrawerList = (ListView) findViewById(R.id.drawer);
List<BitmapDrawable> toolsList = new ArrayList<>();
for (int i = 0; i < tools.length(); i++) {
toolsList.add((BitmapDrawable) tools.getDrawable(i));
}
// set the drawer menu in a custom Adapter
toolsDrawerList.setAdapter(new ToolsMenuAdapter(this, R.layout.drawer_item, R.id.tool, toolsList));
tools.recycle();
toolsDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
BitmapDrawable img;
final ImageView imgView = (ImageView) view.findViewById(R.id.tool);
Context context = getApplicationContext();
// we can not use 'cameraPreview' to retrieve the 'mCamera' object
VideOSCCameraFragment camPreview = (VideOSCCameraFragment) fragmentManager.findFragmentByTag("CamPreview");
camera = camPreview.mCamera;
LayoutInflater inflater = getLayoutInflater();
switch (i) {
// ... other cases...
case 2:
if (!isColorModePanelOpen) {
int y = (int) view.getY();
// create pop-out
final View modePanel = inflater.inflate(R.layout.color_mode_panel, (FrameLayout) camView, true);
isColorModePanelOpen = true;
// try to lock the main menu drawer - didn't work for me
toolsDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN, toolsDrawerList);
final View modePanelInner = modePanel.findViewById(R.id.color_mode_panel);
// set the vertical position of the pop-out
ActivityHelpers.setMargins(modePanelInner, 0, y, 0, 0);
// set actions for each item in the pop-out
for (int k = 0; k < ((ViewGroup) modePanelInner).getChildCount(); k++) {
final Context iContext = context;
View button = ((ViewGroup) modePanelInner).getChildAt(k);
button.setOnClickListener(new View.OnClickListener() {
#Override
// FIXME: touches seem to get swallowed by the DrawerLayout first
public void onClick(View view) {
switch (view.getId()) {
case R.id.mode_rgb:
Log.d(TAG, "rgb");
imgView.setImageDrawable(ContextCompat.getDrawable(iContext, R.drawable.rgb));
break;
case R.id.mode_rgb_inv:
Log.d(TAG, "rgb inverted");
imgView.setImageDrawable(ContextCompat.getDrawable(iContext, R.drawable.rgb_inv));
break;
case R.id.mode_r:
Log.d(TAG, "red");
imgView.setImageDrawable(ContextCompat.getDrawable(iContext, R.drawable.r));
break;
case R.id.mode_g:
Log.d(TAG, "green");
imgView.setImageDrawable(ContextCompat.getDrawable(iContext, R.drawable.g));
break;
case R.id.mode_b:
Log.d(TAG, "blue");
imgView.setImageDrawable(ContextCompat.getDrawable(iContext, R.drawable.b));
break;
default:
imgView.setImageDrawable(ContextCompat.getDrawable(iContext, R.drawable.rgb));
}
// remove the pop-out
((ViewGroup) modePanelInner.getParent()).removeView(modePanelInner);
isColorModePanelOpen = false;
// unlock the drawer again
toolsDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, Gravity.END);
// now the drawer should finally get closed
toolsDrawerLayout.closeDrawer(Gravity.END);
}
});
}
}
break;
// ... other cases ...
}
});
// open drawer on application start
toolsDrawerLayout.openDrawer(Gravity.END);
}
}
}
Edit:
I found this post that offered me a simple way of preventing my pop-out from being closed by adding the following to my MainActivity.java:
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
// We only want to intercept MotionEvent.ACTION_UP if the pop-out is present
return !(isColorModePanelOpen && event.getAction() == MotionEvent.ACTION_UP) && super.dispatchTouchEvent(event);
}
That worked in so far as the drawer is not being closed immediately when trying to click one of the buttons in the pop-out. Unfortunately, the buttons don't accept clicks (resp. touches with an event action MotionEvent.ACTION_DOWN) either. It seems, as long as the drawer isn't closed again, the whole screen is being blocked from any user interaction.
Can anyone confirm my suspicion? (or prove me wrong)
Thanks
Try this code in onResume() of your Activity
if(condition)
{
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
}
else
{
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
}
Related
I want my floating action button to appear when navigation drawer is open and will disappear when navigation drawer is closed, how do I do this? Here is a image for you to see what I am talking about. Here is the image.
Here is my code for the activity.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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:id="#+id/drawer_layout"
>
<com.google.android.material.navigation.NavigationView
android:id="#+id/drawerNavigationView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/navigation_drawer_header"
app:menu="#menu/navigation_drawer_menu"
android:fitsSystemWindows="true"
app:insetForeground="#android:color/transparent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
android:paddingLeft="20dp"
android:paddingBottom="20dp"
android:paddingTop="40dp">
<ImageView
android:id="#+id/logoutNavigationDrawer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src ="#drawable/icon_logout"
android:layout_centerVertical="true"
/>
<TextView
android:id="#+id/logoutTxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/orangeText"
android:paddingLeft="14dp"
android:textSize="16sp"
android:fontFamily="#font/century_gothic_bold"
android:text="Log out"
android:layout_toEndOf="#+id/logoutNavigationDrawer"
android:layout_toRightOf="#+id/logoutNavigationDrawer"
android:layout_centerVertical="true"/>
</RelativeLayout>
</com.google.android.material.navigation.NavigationView>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/emergencyCallFAB"
android:layout_width="wrap_content"
app:tint="#color/white"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:src="#drawable/emergency_call_button_round"
app:backgroundTint="#color/red"
android:layout_marginStart="370dp"
android:layout_marginEnd="50dp"
android:layout_marginTop="800dp"
android:layout_marginBottom="50dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.drawerlayout.widget.DrawerLayout>
Here is my java code in where I implemented the NavigationDrawer
//Setting Emergency Floating Action Button
emergenyCallFABBtn = findViewById(R.id.emergencyCallFAB);
//Will open the menu, once hamburger button has been clicked
hamburgerMenuButton = findViewById(R.id.hamburgerMenuIcon);
hamburgerMenuButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
drawerLayout.openDrawer(GravityCompat.START);
}
});
drawerLayout.setScrimColor(Color.parseColor("#00000000")); // set screen color behind navigation , this is what makes screen behind navigation looks as same color
//NavigationDrawer Function
navigationView.bringToFront();
ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(Location.this, drawerLayout,
R.string.navigation_drawer_open, R.string.navigation_drawer_close){
public void onDrawerOpened(View drawerView){
super.onDrawerClosed(drawerView);
emergenyCallFABBtn.setVisibility(View.VISIBLE); // make it visible and bring to front
emergenyCallFABBtn.bringToFront();
}
#Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
emergenyCallFABBtn.setVisibility(View.VISIBLE);
emergenyCallFABBtn.setAlpha(slideOffset); // makes it visible it animation , as drawer opens button becomes less faded and vice versa in case of close
}
public void onDrawerClosed(View view){
super.onDrawerClosed(view);
emergenyCallFABBtn.setVisibility(View.GONE); // hide button on drawer close
}
};
actionBarDrawerToggle.setDrawerIndicatorEnabled(false);
drawerLayout.addDrawerListener(actionBarDrawerToggle);
actionBarDrawerToggle.syncState();
navigationView.setItemIconTintList(null);
navigationView.setNavigationItemSelectedListener(Location.this);
emergenyCallFABBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(Location.this, EmergencyCall.class);
startActivity(intent);
Toast.makeText(Location.this, "Clicked on Emergency Call", Toast.LENGTH_SHORT).show();
}
});
Here is my onNavigationItemSelected and my onBackPressed function
//Case switch function for the hamburger menu.
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.homeNavigationDrawer:
Intent homeNavDrawer = new Intent(Location.this, TrackActivity.class);
startActivity(homeNavDrawer);
break;
case R.id.profileNavigationDrawer:
Intent profileNavDrawer = new Intent(Location.this, Profile.class);
startActivity(profileNavDrawer);
break;
case R.id.changeCityNavigationDrawer:
Intent changeCityNavDrawer = new Intent(Location.this, NCR.class);
startActivity(changeCityNavDrawer);
break;
// case R.id.nav_logout:
// try {
// auth.signOut();
// Intent i = new Intent(getApplicationContext(), Location.class);
// startActivity(i);
// // signed out
// } catch (Exception e) {
// // Error handling!
// }
// break;
}
return true;
}
#Override
public void onBackPressed() {
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (drawerLayout.isDrawerOpen(navigationView)) {
View content = findViewById(R.id.emergencyCallFAB); // find the id of the view you want to check for clicable
int[] contentLocation = new int[2];
content.getLocationOnScreen(contentLocation);
Rect rect = new Rect(contentLocation[0],
contentLocation[1],
contentLocation[0] + content.getWidth(),
contentLocation[1] + content.getHeight());
if ((rect.contains((int) event.getX(), (int) event.getY()))) { // your view is clicked , perform you action
emergenyCallFAB.performClick();
isOutSideClicked = false;
} else { // clicked outside the button
isOutSideClicked = true;
}
}
}
return super.dispatchTouchEvent(event);
}
Update: There is Error now.
I have made changes to your code to make fab focus, and added comments where I made a change , let me know if anything still unclear.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.navigation.NavigationView
android:id="#+id/drawerNavigationView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/navigation_drawer_header"
app:insetForeground="#android:color/transparent"
app:menu="#menu/navigation_drawer_menu">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
android:paddingLeft="20dp"
android:paddingTop="40dp"
android:paddingBottom="20dp">
<ImageView
android:id="#+id/logoutNavigationDrawer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:src="#drawable/ic_launcher_background" />
<TextView
android:id="#+id/logoutTxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="#+id/logoutNavigationDrawer"
android:layout_toRightOf="#+id/logoutNavigationDrawer"
android:paddingLeft="14dp"
android:text="Log out"
android:textColor="#color/colorPrimaryDark"
android:textSize="16sp" />
</RelativeLayout>
</com.google.android.material.navigation.NavigationView>
<!-- added relative layout as you didn't have any view group using UI to distort in different devices-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- removed extra params , set visiblity gone to hide first time -->
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/emergencyCallFAB"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_centerVertical="true"
android:layout_marginEnd="20dp"
android:visibility="gone"
android:layout_marginBottom="20dp"
android:src="#android:drawable/sym_call_incoming"/>
</RelativeLayout>
</androidx.drawerlayout.widget.DrawerLayout>
MainActivity
drawerLayout = findViewById(R.id.drawer_layout);
drawerLayout.setScrimColor(Color.parseColor("#00000000")); // set screen color behind navigation , this is what makes screen behind navigation looks as same color
navigationView = findViewById(R.id.drawerNavigationView);
emergenyCall = findViewById(R.id.emergencyCallFAB);
//NavigationDrawer Function
navigationView.bringToFront();
ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout,
R.string.navigation_drawer_open, R.string.navigation_drawer_close){
public void onDrawerOpened(View drawerView){
super.onDrawerClosed(drawerView);
emergenyCall.setVisibility(View.VISIBLE); // make it visible and bring to front
emergenyCall.bringToFront();
}
#Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
emergenyCall.setVisibility(View.VISIBLE);
emergenyCall.setAlpha(slideOffset); // makes it visible in animation , as drawer opens button becomes less faded and vice versa in case of close.
}
public void onDrawerClosed(View view){
super.onDrawerClosed(view);
emergenyCall.setVisibility(View.GONE); // hide button on drawer close
}
};
actionBarDrawerToggle.setDrawerIndicatorEnabled(false);
drawerLayout.addDrawerListener(actionBarDrawerToggle);
actionBarDrawerToggle.syncState();
navigationView.setItemIconTintList(null);
Update : To make FAB clickable to need to override dispatchTouchEvent and detect the touch on your button
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (drawerLayout.isDrawerOpen(navigationView)) {
View content = findViewById(R.id.emergencyCallFAB); // find the id of the view you want to check for clicable
int[] contentLocation = new int[2];
content.getLocationOnScreen(contentLocation);
Rect rect = new Rect(contentLocation[0],
contentLocation[1],
contentLocation[0] + content.getWidth(),
contentLocation[1] + content.getHeight());
if ((rect.contains((int) event.getX(), (int) event.getY()))) { // your view is clicked , perform you action
emergenyCall.performClick();
isOutSideClicked = false;
} else { // clicked outside the button
isOutSideClicked = true;
}
}
}
return super.dispatchTouchEvent(event);
}
Final Result
Note: These are randomly generated addresses
Hey Guys, Learning Xamarin and I am trying to scroll my Frame Layour down and reveal a search bar for my list view. Here is what is happening:
I color coded my layouts to see if the sizes where a problem, but I dont think they are since my orange layout is plenty big to hold my two entries. Am I using the wrong layouts for this kind of application? I would appreciate any help!
Here is my translation code:
frameLayout.Animate().TranslationYBy(editSearch.Height).SetDuration(500).Start();
And my layout file:
<android.support.v4.widget.SwipeRefreshLayout 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:id="#+id/swipeLayout">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxHeight="100dp"
android:id="#+id/frameLayoutParent"
android:background="#android:color/holo_green_dark">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/frameLayout"
android:background="#android:color/holo_green_light">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="300dp"
android:background="#android:color/holo_orange_light">
<Button
android:text="Add New Address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/addNewAddress"
android:maxHeight="20dp" />
</LinearLayout>
<ListView
android:paddingTop="50dp"
android:minWidth="25px"
android:minHeight="300dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/myListView"
android:maxHeight="300dp"/>
</FrameLayout>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/editSearch"
android:hint="Search ZipCodes"
android:textColor="#000"/>
</FrameLayout>
</android.support.v4.widget.SwipeRefreshLayout>
EDIT:
Here is my OnOptionsItemSelected Code, where my animation is triggered.
public override bool OnOptionsItemSelected(IMenuItem item)
{
switch (item.ItemId)
{
case Resource.Id.action_search:
//search icon has been clicked
if (isAnimating)
return true;
else
{
if (animateBool)
{
//list view is up
animation anim = new animation(myListView, myListView.Height - editSearch.Height);
anim.Duration = 500;
myListView.StartAnimation(anim);
anim.AnimationStart += Anim_AnimationStartDown; //listener for when animation has started
anim.AnimationEnd += Anim_AnimationEndDown;
classSwipeRefresh.Animate().TranslationYBy(editSearch.Height).SetDuration(500).Start();
}
else
{
animation anim = new animation(myListView, myListView.Height + editSearch.Height);
anim.Duration = 500;
myListView.StartAnimation(anim);
anim.AnimationStart += Anim_AnimationStartUp; //listener for when animation has started
anim.AnimationEnd += Anim_AnimationEndUp;
classSwipeRefresh.Animate().TranslationYBy(-editSearch.Height).SetDuration(500).Start();
}
animateBool = !animateBool;
return true;
}
default:
return base.OnOptionsItemSelected(item);
}
}
Learning Xamarin and I am trying to scroll my Frame Layour down and reveal a search bar for my list view. Here is what is happening:
I use your code to test, but I have no problem when translating by Y in SwipeRefreshLayout__Refresh event.
public class MainActivity : AppCompatActivity
{
string[] items;
ListView listview1;
SwipeRefreshLayout swiplayout;
FrameLayout framelayout;
EditText edittext;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
listview1 = FindViewById<ListView>(Resource.Id.myListView);
swiplayout = FindViewById<SwipeRefreshLayout>(Resource.Id.swipeLayout);
framelayout = FindViewById<FrameLayout>(Resource.Id.frameLayout);
edittext = FindViewById<EditText>(Resource.Id.editSearch);
swiplayout.Refresh += Swiplayout_Refresh;
items = new string[] { "Vegetables", "Fruits", "Flower Buds", "Legumes", "Bulbs", "Tubers" };
listview1.Adapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleListItem1, items);
}
private void Swiplayout_Refresh(object sender, EventArgs e)
{
framelayout.Animate().TranslationYBy(edittext.Height).SetDuration(500).Start();
}
}
This is my screenshot:
If you want to filter ListView, I suggest you can use SearchView in Toolbar to filter listview data, please take a look this sample:
https://github.com/Cheesebaron/SearchView-Sample/tree/master/SearchViewSample
I am trying to create a horizontal LinearLayout which is wider than the screen of the device. It contains a Button which will move the layout to view the part outside the screen when it is clicked. The problem is that android is not creating the part outside the screen, so when I press the button, the view moves to show black screen where the remaining view should have been.
My code-
MainActivity.java
public class MainActivity extends BaseGameActivity implements OnClickListener {
private Context mContext;
private int mScreenHeight;
private int mScreenWidth;
private LinearLayout mViewContainer;
private View mTransparentContainer;
private Button mSliderBtn;
private View mSlidingView;
private View mHomeView;
private int mSlidingWidth;
private boolean mIsSlidingMenuVisible = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = getApplicationContext();
mScreenHeight = UserScreen.getHeight(mContext);
mScreenWidth = UserScreen.getWidth(mContext);
mSlidingWidth = (int) (getResources().getDimension(R.dimen.sliding_menu_offset) + 0.5f);
mViewContainer = new LinearLayout(mContext);
mViewContainer.setOrientation(LinearLayout.HORIZONTAL);
mViewContainer.setLayoutParams(new LinearLayout.LayoutParams(mScreenWidth + mSlidingWidth, mScreenHeight));
setContentView(mViewContainer);
LinearLayout homeContainer = new LinearLayout(mContext);
LinearLayout.LayoutParams homeContainerParams = new LinearLayout.LayoutParams(mScreenWidth, LayoutParams.MATCH_PARENT);
mHomeView = getLayoutInflater().inflate(R.layout.activity_main, homeContainer);
mHomeView.setBackgroundColor(0x80ffffff);
mViewContainer.addView(homeContainer, homeContainerParams);
LinearLayout slidingContainer = new LinearLayout(mContext);
LinearLayout.LayoutParams slidingContainerParams = new LinearLayout.LayoutParams(mSlidingWidth, LayoutParams.MATCH_PARENT);
mSlidingView = getLayoutInflater().inflate(R.layout.slider_menu, slidingContainer);
mViewContainer.addView(slidingContainer, slidingContainerParams);
initUi();
// other code
}
public void initUi() {
mSliderBtn = (Button) mHomeView.findViewById(R.id.button_slider);
mSliderBtn.setOnClickListener(this);
mTransparentContainer = mHomeView.findViewById(R.id.transparent_container);
mTransparentContainer.setOnClickListener(this);
// other code
}
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.button_slider:
mSliderBtn.setEnabled(false);
mIsSlidingMenuVisible = true;
mTransparentContainer.setVisibility(View.VISIBLE);
mTransparentContainer.bringToFront();
tableMoveLeft(mViewContainer, mSlidingWidth);
break;
case R.id.transparent_container:
mSliderBtn.setEnabled(true);
mIsSlidingMenuVisible = false;
mTransparentContainer.setVisibility(View.GONE);
tableMoveRight(mViewContainer, mSlidingWidth);
break;
// other cases
}
}
// Animation Functions
public void tableMoveLeft(final View container, final float newPos){
ObjectAnimator moveLeft = ObjectAnimator.ofFloat(container, "translationX", 0, -newPos);
moveLeft.setDuration(300);
moveLeft.start();
}
public void tableMoveRight(final View container, final float newPos){
ObjectAnimator moveRight = ObjectAnimator.ofFloat(container, "translationX", -newPos, 0);
moveRight.setDuration(300);
moveRight.start();
}
// other code
}
activity_main.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:background="#drawable/bg_menu"
tools:context="${relativePackage}.${activityClass}" >
<!-- other code -->
<Button
android:id="#+id/button_slider"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginRight="10dip"
android:layout_marginTop="30dip"
android:background="#drawable/move" />
<View
android:id="#+id/transparent_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#80800000"
android:visibility="gone" />
</RelativeLayout>
slider_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/image_info_bg_popup"
android:orientation="vertical" >
<!-- Other Code -->
</LinearLayout>
My Output on clicking the button
Using a ScrollView is not a solution because I dont want the user to freely scroll the view, and also there is a ViewPager in the main layout which will conflict with it. Please help. Thanks.
Android officially introduced sliding panel menu by introducing a newer concept called Navigation Drawer. Most of the time Sliding Menu (Navigation Drawer) will be hidden and can be shown by swiping the screen from left edge to right or tapping the app icon on the action bar.
For example, the following layout uses a DrawerLayout with two child views: a FrameLayout to contain the main content (populated by a Fragment at runtime), and a ListView for the navigation drawer.
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The main content view -->
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- The navigation drawer -->
<ListView android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#111"/>
for additional info about NavigationDrawer, please take a look into these links :
http://www.androidhive.info/2013/11/android-sliding-menu-using-navigation-drawer/
http://developer.android.com/training/implementing-navigation/nav-drawer.html
The problem was that the layout with size larger than screen size was set as the root container of the activity. I don't know what was the problem caused by that, but to fix it-
#Override
public void onCreate(Bundle savedInstanceState) {
super(savedInstanceState);
LinearLayout rootContainer = new LinearLayout(mContext);
setContentView(rootContainer);
// other code
rootContainer.addView(mViewContainer);
}
Any explanations of why having a root view larger than screen size created a problem are welcome :)
I have an Action Bar. It has two drawers coming from left and right.
For the left, I'm using the Action Bar Toggle button on the top left as shown in the image below. Can I put that toggle button in the right side too?
I can use a custom linear layout view (ImageView - EditText - ImageView) to add it to the getActionBar.setCustomView() method and implement click listeners on the imageview's to show drawers.
My question is, does android provide a right toggle button like the left?
You have to make some changes in your .xml file and Java code.
First Step
Let start with your .xml file.
Code
First FrameLayout: represent to action-bar, note we have ImageView called drawer_indicator and it's our right toggle.
Second FrameLayout: represent our fragment containers.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- Action-bar looking view -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="#dimen/actionbar_dimen"
android:background="#color/blue" >
<ImageView
android:id="#+id/drawer_indicator"
android:layout_width="#dimen/actionbar_dimen"
android:layout_height="#dimen/actionbar_dimen"
android:layout_gravity="right"
android:background="#drawable/drawer_selector"
android:scaleType="centerInside" />
<TextView
android:id="#+id/indicator_style"
android:layout_width="wrap_content"
android:layout_height="#dimen/actionbar_dimen"
android:layout_gravity="center"
android:background="#drawable/drawer_selector"
android:gravity="center"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:text="#string/tests"
android:textColor="#android:color/white"
android:textStyle="bold" />
</FrameLayout>
<!-- Action-bar Ends -->
<!-- Drawer Layout -->
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
<!-- our Fragment Content-->
<FrameLayout
android:id="#+id/view_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/light_gray"
android:gravity="center" />
<!-- slide menu android:layout_gravity="end" to make it come from right-->
<LinearLayout
android:id="#+id/drawer_content"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="end"
android:background="#android:color/white"
android:gravity="center"
android:orientation="vertical" >
<!-- drawer list-->
<ListView
android:id="#+id/DrawerList"
android:layout_width="240dp"
android:layout_height="match_parent"
/>
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
Second Step
Get DrawerArrowDrawable from this link
private DrawerArrowDrawable drawerArrowDrawable;
private float offset;
private boolean flipped;
ListView DrawerList;
DrawerLayout drawer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// to make activity full screen
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// it must before setContentView
setContentView(R.layout.home_view);
// drawer list
DrawerList = (ListView) findViewById(R.id.DrawerList);
// drawer item list
ArrayList<DrawerItem> Items = new ArrayList<DrawerItem>();
// fill arraylist
Items.add(new DrawerItem(getResources().getString(R.string.tests),
R.drawable.test));
// drawer adapter
DrawerAdapter adapter = new DrawerAdapter(this, Items);
// set adapter to our drawer list
DrawerList.setAdapter(adapter);
// attach listener to drawer list
DrawerList.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// handle select item here
}
});
// initialize our drawer layout
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
// right toggle button
final ImageView imageView = (ImageView) findViewById(R.id.drawer_indicator);
final Resources resources = getResources();
// its custom class
drawerArrowDrawable = new DrawerArrowDrawable(resources);
drawerArrowDrawable.setStrokeColor(resources
.getColor(R.color.light_gray));
imageView.setImageDrawable(drawerArrowDrawable);
drawer.setDrawerListener(new DrawerLayout.SimpleDrawerListener() {
#Override
public void onDrawerSlide(View drawerView, float slideOffset) {
offset = slideOffset;
// Sometimes slideOffset ends up so close to but not quite 1 or 0.
if (slideOffset >= .995) {
flipped = true;
drawerArrowDrawable.setFlip(flipped);
} else if (slideOffset <= .005) {
flipped = false;
drawerArrowDrawable.setFlip(flipped);
}
drawerArrowDrawable.setParameter(offset);
}
});
// attach listener to toggle image view
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openDrawer();
}
});
}
I hope it be clear to you.
I have a layout with a top bar container and a content container. When clicking on a button in the top bar, a vertical menu is displayed using an animation. My minSdkVersion is 9.
This works well when I start the app and I still haven't clicked a menu button (i.e. the content fragment has not changed), but as soon as I have clicked an option (and then replace the fragment in the content_container), the vertical menu behaves erratically. The click event of the menu btn is properly triggered, but the vertical menu is not always shown (but sometimes it is...). However, when I click the button and then touch the screen, the animation (show or hide the menu) starts.
I guess it has something to do with the vertical menu overlapping the content fragment, and then replacing the content fragment modify it in some way, but I can't find any solution.
Anybody can help?
top bar fragment
#Override
public void onActivityCreated (Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
toggleMenu(0);
Button btn_menu = (Button) getView().findViewById(R.id.btn_menu);
btn_menu.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mVerticalMenu.setVisibility(View.VISIBLE);
toggleMenu(1000);
}
});
}
private void toggleMenu(int duration){
if(mMenuIsOpen){
TranslateAnimation anim1 = new TranslateAnimation(0,0,0,-(mHeight-mMenuVerticalOffset));
anim1.setFillAfter(true);
anim1.setDuration(duration);
mVerticalMenu.setAnimation(anim1);
AlphaAnimation anim2 = new AlphaAnimation(0.7f, 0.0f);
anim2.setFillAfter(true);
anim2.setDuration(duration);
menu_option_01.setOnClickListener(null);
menu_option_02.setOnClickListener(null);
menu_option_03.setOnClickListener(null);
mMenuIsOpen = false;
}
else{
TranslateAnimation anim1 = new TranslateAnimation(0,0,-(mHeight-mMenuVerticalOffset),0);
anim1.setFillAfter(true);
anim1.setDuration(duration);
mVerticalMenu.setAnimation(anim1);
AlphaAnimation anim2 = new AlphaAnimation(0.0f, 0.7f);
anim2.setFillAfter(true);
anim2.setDuration(duration);
menu_option_01.setOnClickListener(mButtonClickListener);
menu_option_02.setOnClickListener(mButtonClickListener);
menu_option_03.setOnClickListener(mButtonClickListener);
mMenuIsOpen = true;
}
}
private OnClickListener mButtonClickListener = new OnClickListener()
{
public void onClick(View v)
{
toggleMenu(1000);
if(!v.isSelected()){
FragmentTransaction fragmentTransaction = getActivity().getSupportFragmentManager().beginTransaction();
switch(v.getId()){
case R.id.menu_option_01:
// replace content_container by fragment 1
break;
case R.id.btn_02:
// replace content_container by fragment 2
break;
case R.id.btn_03:
// replace content_container by fragment 3
break;
}
}
}
};
private OnClickListener mBgClickListener = new OnClickListener()
{
public void onClick(View v)
{
toggleMenu(1000);
}
};
Main 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" >
<FrameLayout
android:id="#+id/content_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="44dp" />
<FrameLayout
android:id="#+id/top_bar_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false" />
</RelativeLayout>
top bar 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:background="#00000000" >
<LinearLayout
android:id="#+id/vertical_menu"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_marginTop="44dp"
android:background="#ffffff"
android:orientation="vertical"
android:visibility="gone" >
<!-- menu layout -->
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="44dp"
android:background="#ffffff" >
<Button
android:id="#+id/btn_menu"
android:layout_width="50dp"
android:layout_height="44dp"
android:background="#drawable/menubtn" />
<ImageView
android:layout_width="130dp"
android:layout_height="44dp"
android:src="#drawable/logo"
android:layout_alignParentRight="true" />
</RelativeLayout>
</RelativeLayout>
At the end of my Toggle method, I invalidate the root view:
rootView.invalidate();
and now it works. Not quite clear why I must do that though...
I know there is already an accepted answer for this but I had a similar problem and the answer didnt help.
I had a view that I declared at the end of my layout to keep its Z index above its siblings. I had to touch the page to make the animation work.
So I set the Z index again through Java and it worked.
view.bringToFront();