Right now i am working with sliding drawer control with list-view. Here my problem is, i am unable to do swipe with my fingers over the listview, but the menu(Toggle) button is working fine. Has anyone have ever met situation like this, if so, please help me to solve this issue. Suggestion please.
I hope the below image will give you clear idea about my question
Here is my working source for reference
activity_main.xml
<com.entropy.slidingmenu2.layout.MainLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- This holds our menu -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="@+id/activity_main_menu_listvie"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#B4D609"
android:cacheColorHint="#00000000" >
</ListView>
</LinearLayout>
<!-- This holds our content-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- This acts as Actionbar -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#96D6E3"
android:orientation="horizontal" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="toggleMenu"
android:text="Menu"
android:id="@+id/activity_main_content_button_menu" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:gravity="center"
android:id="@+id/activity_main_content_title"
android:layout_weight="1" />
</LinearLayout>
<!-- This is where fragment will show up -->
<FrameLayout
android:id="@+id/activity_main_content_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
</LinearLayout>
</com.entropy.slidingmenu2.layout.MainLayout>
fragment_listview.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white" >
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/fragment_listview_listview" />
</RelativeLayout>
MainActiviy.java
public class MainActivity extends FragmentActivity {
MainLayout mainLayout;
private ListView lvMenu;
private String[] lvMenuItems;
Button btMenu;
TextView tvTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mainLayout = (MainLayout)this.getLayoutInflater().inflate(R.layout.activity_main, null);
setContentView(mainLayout);
lvMenuItems = getResources().getStringArray(R.array.menu_items);
lvMenu = (ListView) findViewById(R.id.activity_main_menu_listvie);
lvMenu.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, lvMenuItems));
lvMenu.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
onMenuItemClick(parent, view, position, id);
}
});
btMenu = (Button) findViewById(R.id.activity_main_content_button_menu);
btMenu.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// Show/hide the menu
toggleMenu(v);
}
});
tvTitle = (TextView) findViewById(R.id.activity_main_content_title);
// Add FragmentMain as the initial fragment
FragmentManager fm = MainActivity.this.getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
FragmentMain fragment = new FragmentMain();
ft.add(R.id.activity_main_content_fragment, fragment);
ft.commit();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void toggleMenu(View v){
mainLayout.toggleMenu();
}
private void onMenuItemClick(AdapterView<?> parent, View view, int position, long id) {
String selectedItem = lvMenuItems[position];
String currentItem = tvTitle.getText().toString();
// Do nothing if selectedItem is currentItem
if(selectedItem.compareTo(currentItem) == 0) {
mainLayout.toggleMenu();
return;
}
FragmentManager fm = MainActivity.this.getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
Fragment fragment = null;
if(selectedItem.compareTo("ListView") == 0) {
fragment = new FragmentListView();
}
if(fragment != null) {
// Replace current fragment by this new one
ft.replace(R.id.activity_main_content_fragment, fragment);
ft.commit();
// Set title accordingly
tvTitle.setText(selectedItem);
}
mainLayout.toggleMenu();
}
@Override
public void onBackPressed() {
if (mainLayout.isMenuShown()) {
mainLayout.toggleMenu();
}
else {
super.onBackPressed();
}
}}
FragmentListView.java
public class FragmentListView extends Fragment {
ListView listView;
public FragmentListView() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_listview, null);
String[] listViewItems = new String[] {"Sachin Tendulkar", "Sourav Ganguly", "Rahul Dravid", "Virendar Shewag",
"Yuvraj Singh","Mahendra Singh Dhoni","Irfan Pathan","Bhuvaneshawar kumar","Harbhajan Singh",
"Zaheer Khan","Ashish Nehra","Virat Kohli"};
listView = (ListView) view.findViewById(R.id.fragment_listview_listview);
listView.setAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, listViewItems));
return view;
}}
MainLayout.java
public class MainLayout extends LinearLayout {
// Duration of sliding animation, in miliseconds
private static final int SLIDING_DURATION = 500;
// Query Scroller every 16 miliseconds
private static final int QUERY_INTERVAL = 16;
// MainLayout width
int mainLayoutWidth;
// Sliding menu
private View menu;
// Main content
private View content;
// menu does not occupy some right space
// This should be updated correctly later in onMeasure
private static int menuRightMargin = 150;
// The state of menu
private enum MenuState {
HIDING,
HIDDEN,
SHOWING,
SHOWN,
};
// content will be layouted based on this X offset
// Normally, contentXOffset = menu.getLayoutParams().width = this.getWidth - menuRightMargin
private int contentXOffset;
// menu is hidden initially
private MenuState currentMenuState = MenuState.HIDDEN;
// Scroller is used to facilitate animation
private Scroller menuScroller = new Scroller(this.getContext(),
new EaseInInterpolator());
// Used to query Scroller about scrolling position
// Note: The 3rd paramter to startScroll is the distance
private Runnable menuRunnable = new MenuRunnable();
private Handler menuHandler = new Handler();
// Previous touch position
int prevX = 0;
// Is user dragging the content
boolean isDragging = false;
// Used to facilitate ACTION_UP
int lastDiffX = 0;
// Constructor
// 3 parameters constructor seems to be unavailable in 2.3
/*
public MainLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
*/
public MainLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MainLayout(Context context) {
super(context);
}
// Overriding LinearLayout core methods
// Ask all children to measure themselves and compute the measurement of this
// layout based on the children
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mainLayoutWidth = MeasureSpec.getSize(widthMeasureSpec);
menuRightMargin = mainLayoutWidth * 10 / 100;
// Nothing to do, since we only care about how to layout
}
// This is called when MainLayout is attached to window
// At this point it has a Surface and will start drawing.
// Note that this function is guaranteed to be called before onDraw
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
// Get our 2 child View
menu = this.getChildAt(0);
content = this.getChildAt(1);
// Attach View.OnTouchListener
content.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return MainLayout.this.onContentTouch(v, event);
}
});
// Initially hide the menu
menu.setVisibility(View.GONE);
}
// Called from layout when this view should assign a size and position to each of its children
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
//Log.d("MainLayout.java onLayout()", "left " + left + " top " + top + " right " + right + " bottom " + bottom);
//Log.d("MainLayout.java onLayout()", "getHeight " + this.getHeight() + " getWidth " + this.getWidth());
// True if MainLayout 's size and position has changed
// If true, calculate child views size
if(changed) {
// Note: LayoutParams are used by views to tell their parents how they want to be laid out
//Log.d("MainLayout.java onLayout()", "changed " + changed);
// content View occupies the full height and width
LayoutParams contentLayoutParams = (LayoutParams)content.getLayoutParams();
contentLayoutParams.height = this.getHeight();
contentLayoutParams.width = this.getWidth();
// menu View occupies the full height, but certain width
LayoutParams menuLayoutParams = (LayoutParams)menu.getLayoutParams();
menuLayoutParams.height = this.getHeight();
menuLayoutParams.width = this.getWidth() - menuRightMargin;
}
// Layout the child views
menu.layout(left, top, right - menuRightMargin, bottom);
content.layout(left + contentXOffset, top, right + contentXOffset, bottom);
}
// Custom methods for MainLayout
// Used to show/hide menu accordingly
public void toggleMenu() {
// Do nothing if sliding is in progress
if(currentMenuState == MenuState.HIDING || currentMenuState == MenuState.SHOWING)
return;
switch(currentMenuState) {
case HIDDEN:
currentMenuState = MenuState.SHOWING;
menu.setVisibility(View.VISIBLE);
menuScroller.startScroll(0, 0, menu.getLayoutParams().width,
0, SLIDING_DURATION);
break;
case SHOWN:
currentMenuState = MenuState.HIDING;
menuScroller.startScroll(contentXOffset, 0, -contentXOffset,
0, SLIDING_DURATION);
break;
default:
break;
}
// Begin querying
menuHandler.postDelayed(menuRunnable, QUERY_INTERVAL);
// Invalite this whole MainLayout, causing onLayout() to be called
this.invalidate();
}
// Query Scroller
protected class MenuRunnable implements Runnable {
@Override
public void run() {
boolean isScrolling = menuScroller.computeScrollOffset();
adjustContentPosition(isScrolling);
}
}
// Adjust content View position to match sliding animation
private void adjustContentPosition(boolean isScrolling) {
int scrollerXOffset = menuScroller.getCurrX();
//Log.d("MainLayout.java adjustContentPosition()", "scrollerOffset " + scrollerOffset);
// Translate content View accordingly
content.offsetLeftAndRight(scrollerXOffset - contentXOffset);
contentXOffset = scrollerXOffset;
// Invalite this whole MainLayout, causing onLayout() to be called
this.invalidate();
// Check if animation is in progress
if (isScrolling)
menuHandler.postDelayed(menuRunnable, QUERY_INTERVAL);
else
this.onMenuSlidingComplete();
}
// Called when sliding is complete
private void onMenuSlidingComplete() {
switch (currentMenuState) {
case SHOWING:
currentMenuState = MenuState.SHOWN;
break;
case HIDING:
currentMenuState = MenuState.HIDDEN;
menu.setVisibility(View.GONE);
break;
default:
return;
}
}
// Make scrolling more natural. Move more quickly at the end
// See the formula here http://cyrilmottier.com/2012/05/22/the-making-of-prixing-fly-in-app-menu-part-1/
protected class EaseInInterpolator implements Interpolator {
@Override
public float getInterpolation(float t) {
return (float)Math.pow(t-1, 5) + 1;
}
}
// Is menu completely shown
public boolean isMenuShown() {
return currentMenuState == MenuState.SHOWN;
}
// Handle touch event on content View
public boolean onContentTouch(View v, MotionEvent event) {
// Do nothing if sliding is in progress
if(currentMenuState == MenuState.HIDING || currentMenuState == MenuState.SHOWING)
return false;
// getRawX returns X touch point corresponding to screen
// getX sometimes returns screen X, sometimes returns content View X
int curX = (int)event.getRawX();
int diffX = 0;
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
//Log.d("MainLayout.java onContentTouch()", "Down x " + curX);
prevX = curX;
return true;
case MotionEvent.ACTION_MOVE:
//Log.d("MainLayout.java onContentTouch()", "Move x " + curX);
// Set menu to Visible when user start dragging the content View
if(!isDragging) {
isDragging = true;
menu.setVisibility(View.VISIBLE);
}
// How far we have moved since the last position
diffX = curX - prevX;
// Prevent user from dragging beyond border
if(contentXOffset + diffX <= 0) {
// Don't allow dragging beyond left border
// Use diffX will make content cross the border, so only translate by -contentXOffset
diffX = -contentXOffset;
} else if(contentXOffset + diffX > mainLayoutWidth - menuRightMargin) {
// Don't allow dragging beyond menu width
diffX = mainLayoutWidth - menuRightMargin - contentXOffset;
}
// Translate content View accordingly
content.offsetLeftAndRight(diffX);
contentXOffset += diffX;
// Invalite this whole MainLayout, causing onLayout() to be called
this.invalidate();
prevX = curX;
lastDiffX = diffX;
return true;
case MotionEvent.ACTION_UP:
//Log.d("MainLayout.java onContentTouch()", "Up x " + curX);
Log.d("MainLayout.java onContentTouch()", "Up lastDiffX " + lastDiffX);
// Start scrolling
// Remember that when content has a chance to cross left border, lastDiffX is set to 0
if(lastDiffX > 0) {
// User wants to show menu
currentMenuState = MenuState.SHOWING;
// No need to set to Visible, because we have set to Visible in ACTION_MOVE
//menu.setVisibility(View.VISIBLE);
//Log.d("MainLayout.java onContentTouch()", "Up contentXOffset " + contentXOffset);
// Start scrolling from contentXOffset
menuScroller.startScroll(contentXOffset, 0, menu.getLayoutParams().width - contentXOffset,
0, SLIDING_DURATION);
} else if(lastDiffX < 0) {
// User wants to hide menu
currentMenuState = MenuState.HIDING;
menuScroller.startScroll(contentXOffset, 0, -contentXOffset,
0, SLIDING_DURATION);
}
// Begin querying
menuHandler.postDelayed(menuRunnable, QUERY_INTERVAL);
// Invalite this whole MainLayout, causing onLayout() to be called
this.invalidate();
// Done dragging
isDragging = false;
prevX = 0;
lastDiffX = 0;
return true;
default:
break;
}
return false;
}}
0 comments:
Post a Comment