I have three tabs and hiding the Action Bar on the middle tab. The third tab had pull to refresh. Android does a great job of animating the sliding in and out of the Action Bar but when I pull to refresh on the third tab and switch to the middle tab (where the Action Bar is hidden) I see the following:
The action bar is hidden from the PageAdapter and hidden as follows:
#Override
public void onPageSelected(int position) {
if (position == 1) {
mActionBar.hide();
} else {
mActionBar.show();
}
}
Pull to Refresh is implemented in a fragment (third tab) with the layout as:
<?xml version="1.0" encoding="utf-8"?>
<uk.co.senab.actionbarpulltorefresh.extras.actionbarsherlock.PullToRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ptr_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/grey_canvas_bg"
android:orientation="vertical"
>
<se.emilsjolander.stickylistheaders.StickyListHeadersListView
android:id="#+id/list_feed"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</uk.co.senab.actionbarpulltorefresh.extras.actionbarsherlock.PullToRefreshLayout>
and initialised in the OnCreateView as follows:
mPullToRefreshLayout = (PullToRefreshLayout) view.findViewById(R.id.ptr_layout);
ActionBarPullToRefresh.from(getActivity())
.allChildrenArePullable()
.useViewDelegate(StickyListHeadersListView.class, new ViewDelegate() {
#Override
public boolean isReadyForPull(View view, float v, float v2) {
View childView = updatesListView.getChildAt(0);
int top = (childView == null) ? 0 : childView.getTop();
return top >= 0;
}
})
.listener(this)
.setup(mPullToRefreshLayout);
Thanks for any help!
Related
I've been converting a project to Kotlin and discovered a problem. The context menu from the java code is broken in the generated kotlin.This is a simplified test of the source from the project. It consists of only a main activity with a single layout and a context menu. The java version works but the kotlin version crashes. The only thing I can think of that is unusual is that the view I'm registering is an imageView in a RelativeLayout.
java.lang.NullPointerException:
Parameter specified as non-null is null:
method kotlin.jvm.internal.Intrinsics.checkNotNullParameter
, parameter menuInfo
at com...MainActivity.onCreateContextMenu(MainActivity.kt)
at android.view.View.createContextMenu(View.java:8392)
at com.android.internal.view.menu.ContextMenuBuilder
.show(ContextMenuBuilder.java:81)
at com.android.internal.policy.impl
.PhoneWindow$DecorView
.showContextMenuForChild(PhoneWindow.java:2517)
at android.view.ViewGroup.showContextMenuForChild(ViewGroup.java:658)
MainActivity.java is:
public class MainActivity extends AppCompatActivity {
private static int animationSpeed = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerForContextMenu(findViewById(R.id.imageView));
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.speed_select, menu);
menu.getItem(animationSpeed).setChecked(true);
}
#Override
public boolean onContextItemSelected(MenuItem item) {
int itemId = item.getItemId();
boolean rv = true;
switch(itemId) {
case R.id.animate_slow: animationSpeed = 0; break;
case R.id.animate_normal: animationSpeed = 1; break;
case R.id.animate_fast: animationSpeed = 2; break;
default: Log.d("onContextItemSelected", String.format(
"menu item unhandled:0x%08x", itemId)
);
rv = false;
}
return rv;
}
}
MainActivity.kt is:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
registerForContextMenu(findViewById(R.id.imageView))
}
override fun onCreateContextMenu(menu: ContextMenu, v: View,
menuInfo: ContextMenuInfo) {
super.onCreateContextMenu(menu, v, menuInfo)
val inflater = menuInflater
inflater.inflate(R.menu.speed_select, menu)
menu.getItem(animationSpeed).isChecked = true
}
override fun onContextItemSelected(item: MenuItem): Boolean {
val itemId = item.itemId
var rv = true
when (itemId) {
R.id.animate_slow -> animationSpeed = 0
R.id.animate_normal -> animationSpeed = 1
R.id.animate_fast -> animationSpeed = 2
else -> {
Log.d("onContextItemSelected", String.format(
"menu item unhandled:0x%08x", itemId))
rv = false
}
}
return rv
}
companion object {
private var animationSpeed = 0
}
}
My menu file is:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<group
android:checkableBehavior="single"
android:id="#+id/animate_speed" >
<item android:id="#+id/animate_slow"
android:title="#string/slow" />
<item android:id="#+id/animate_normal"
android:title="#string/normal" />
<item android:id="#+id/animate_fast"
android:title="#string/fast" />
</group>
</menu>
The activity layout is:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/relative_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/imageView"
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_centerInParent="true"
android:background="#drawable/andy"
/>
</RelativeLayout>
I've tried breaking in the onCreateContextMenu but never get there.
I'm using Kotlin 1.40, AndroidStudio 4.01, SDK 30, and gradle 4.01. I've been looking at the docs and the code for a couple of days now and to me, the generated kotlin looks right.Thanks!
Thanks to John Healy below this was solved.
John said he thought it might be in Kotlin's null-safety handling. I doubted so I added a log statement to the working Java code and menuInfo was coming in as a null. I added a #Nullable annotation to the Java declaration which gave me:
public void onCreateContextMenu(
ContextMenu menu, View v,
#Nullable ContextMenu.ContextMenuInfo menuInfo)
Testing of the Java code showed the compiler and lint were happy and the code still ran. I again ran the jave through the conversion process and the resulting kotlin signature for the function is:
override fun onCreateContextMenu(
menu: ContextMenu, v: View,
menuInfo: ContextMenuInfo?)
I tested the Kotlin and it now works too!
NOTE: for your edification and amusement I posted the source on
git hub.
I'm only puting up this reply to my question so people will notice a solution was found thanks to a commentor. This fix only applies if you are using a menu list rather than creating individual menu items and the fix is only necessary for Kotlin because of the way in which Kotlin handles null-safety. Please look at the end of the question and at my comment to that question,
Steve S.
I am using a collapsingToolbarLayout in my application and as long as the menu is not collapsed there is no problem when rotating the phone. But when the menu is collapsed and only the original toolbar is showing the app crashes. The thing is, when only the original toolbar is showing a clickable item appears and disappears when the collapsing toolbar is shown. When rotating the phone, the application does not find this item. How can I solve this?
The activity where the menu is.
private Menu menu;
protected void onCreate(Bundle savedInstanceState) {
...
AppBarLayout mAppBarLayout = findViewById(R.id.appBarLayout2);
mAppBarLayout.addOnOffsetChangedListener(new
AppBarLayout.OnOffsetChangedListener() {
int scrollRange = -1;
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int
verticalOffset) {
if (scrollRange == -1) {
scrollRange = appBarLayout.getTotalScrollRange();
}
if (scrollRange + verticalOffset == 0) {
isShow = true;
showOption();
} else if (isShow) {
isShow = false;
hideOption();
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
this.menu = menu;
getMenuInflater().inflate(R.menu.menu_scrolling, menu);
hideOption();
return true;
}
private void hideOption() {
MenuItem item = menu.findItem(R.id.action_info);
item.setVisible(false);
}
private void showOption() {
MenuItem item = menu.findItem(R.id.action_info);
item.setVisible(true);
}
The relevant code in xml-file:
<android.support.design.widget.AppBarLayout
android:id="#+id/appBarLayout2"
android:layout_width="match_parent"
android:layout_height="128dp"
android:theme="#style/AppTheme.Base"
app:layout_constraintTop_toTopOf="#+id/nestedScrollView">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsTool"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorSecondary"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleGravity="bottom|center"
app:expandedTitleMargin="16dp"
app:expandedTitleTextAppearance="#style/TextAppearance.AppCompat.Display2"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:title="#string/title_expenses">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:navigationIcon="#drawable/ic_action_exit"
app:title="#string/title_expenses"
app:titleTextColor="#android:color/background_light" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
The menu_Scrolling.xml
<menu 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"
tools:context="com.journaldev.collapsingtoolbarlayout.ScrollingActivity">
<item
android:id="#+id/action_info"
android:icon="#drawable/ic_action_add"
android:orderInCategory="200"
android:title="Add"
app:showAsAction="ifRoom" />
</menu>
This is the error message:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.korneliapalm.android.samboappen/com.korneliapalm.android.samboappen.MoneyListActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'android.view.MenuItem android.view.Menu.findItem(int)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3114)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3257)
at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:5039)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4948)
at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1948)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7050)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'android.view.MenuItem android.view.Menu.findItem(int)' on a null object reference
at com.korneliapalm.android.samboappen.MoneyListActivity.showOption(MoneyListActivity.java:163)
at com.korneliapalm.android.samboappen.MoneyListActivity.onCreate(MoneyListActivity.java:51)
at android.app.Activity.performCreate(Activity.java:7327)
at android.app.Activity.performCreate(Activity.java:7318)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3094)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3257)
at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:5039)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4948)
at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1948)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7050)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
The problem is that in onCreate you are calling the methods hideOption() and showOption().
However, oncreate is called before onCreateOptionsMenu which is where you are inflating the menu view. So calling menu.findItem(R.id.action_info); triggers a null pointer.
getMenuInflater().inflate(R.menu.menu_scrolling, menu);
You need to ensure that the menu view is inflated before you call these two methods in onCreate.
private void hideOption() {
if (menu == null) return;
MenuItem item = menu.findItem(R.id.action_info);
item.setVisible(false);
}
private void showOption() {
if (menu == null) return;
MenuItem item = menu.findItem(R.id.action_info);
item.setVisible(true);
}
Activity:
When orientation change occurs,android restarts the running Activity ( onDestroy() is called, followed by onCreate()). If you want to handle inside activity,you cant use: in manifest file for particular activity.
For API 12 and below:
android:configChanges="orientation"
if you are targeting API 13 or above
android:configChanges="orientation|screenSize"
You have not handled orientations in your code. You should try to handle them.
The reason for your crash is that when you rotate your screen following event happens:
Activity gets destroyed.
Activity gets re-created.
AppBarLayout's offset gets changed and the method onOffsetChanged is called.
if (scrollRange + verticalOffset == 0) { condition gets true and showOption(); method is called.
Because the Activity is being re-created, the menu item that is used in showOption(); method is null on the line MenuItem item = menu.findItem(R.id.action_info);
Because the item is null, the code item.setVisible(true); produces a runtime crash of Null Pointer Exception.
The proper way of handling orientations is to implement the following method in your Activity code:
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
// Checks the orientation of the screen
if (newConfig.orientation === Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show()
} else if (newConfig.orientation === Configuration.ORIENTATION_PORTRAIT) {
Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show()
}
}
As a pre-cautionary measure, you can add null checks for avoiding the crashes temporarily like this:
private void hideOption() {
MenuItem item = menu.findItem(R.id.action_info);
if (item != null) {
item.setVisible(false);
} else {
Log.e("Your Class", "hideOption() was called, but menu item was null");
}
}
private void showOption() {
MenuItem item = menu.findItem(R.id.action_info);
if (item != null) {
item.setVisible(true);
} else {
Log.e("Your Class", "showOption() was called, but menu item was null");
}
}
I hope this helps.
Reference link:
https://developer.android.com/guide/topics/resources/runtime-changes
I want to use the ViewPager with the BottomNavigation bar from Aurel Hubert https://github.com/aurelhubert/ahbottomnavigation
I have following code:
My activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.aaron.waller.mrpolitik.MainActivity"
android:id="#+id/content_id">
<com.aurelhubert.ahbottomnavigation.AHBottomNavigation
android:id="#+id/myBottomNavigation_ID"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
and my MainActivity.java:
public class MainActivity extends AppCompatActivity implements AHBottomNavigation.OnTabSelectedListener {
AHBottomNavigation bottomNavigation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().hide();
bottomNavigation = (AHBottomNavigation) findViewById(R.id.myBottomNavigation_ID);
bottomNavigation.setOnTabSelectedListener(this);
bottomNavigation.setDefaultBackgroundColor(Color.BLUE);
this.createNavItems();
}
//Create items, add them to bar, set propertied and set current item
private void createNavItems() {
//CREATE ITEMS
AHBottomNavigationItem ohnemundItem = new AHBottomNavigationItem("Parteien", R.drawable.parteienicon);
AHBottomNavigationItem grinseItem = new AHBottomNavigationItem("Statistiken", R.drawable.statsicon);
AHBottomNavigationItem lachItem = new AHBottomNavigationItem("Fragen", R.drawable.fragenicon);
//ADD THEM to bar
bottomNavigation.addItem(ohnemundItem);
bottomNavigation.addItem(grinseItem);
bottomNavigation.addItem(lachItem);
//set properties
bottomNavigation.setDefaultBackgroundColor(Color.parseColor("#FEFEFE"));
//set current item
bottomNavigation.setCurrentItem(0);
}
#Override
public void onTabSelected(int position, boolean wasSelected) {
if (position == 0) {
ParteienFragment parteienFragment = new ParteienFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.content_id, parteienFragment).commit();
} else if (position == 1) {
StatistikenFragment statistikenFragment = new StatistikenFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.content_id, statistikenFragment).commit();
} else if (position == 2) {
FragenFragment fragenFragment = new FragenFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.content_id, fragenFragment).commit();
}
}
}
I have no clue how to implement a ViewPager in this case.
I have already googled but have found nothing specific to this NavigationBar.
Is it possible at all to add a swipe effect with this navigation bar?
All I want is that I can wipe left and right between my Fragments.
I know it is a bit late but here goes a way of achieving what you pretend. If you want a swipe behaviour you should make a touch event in your activity to detect a swipe. After you detect a swipe it should be simple, just get the current item, and depending on the swipe set the position on the bottom navigation.
Example:
if(isSwipeRight && bottomNavigation.getCurrentItem() > 0)
bottomNavigation.setCurrentItem(bottomNavigation.getCurrentItem()-1);
else if(isSwipeLeft && bottomNavigation.getCurrentItem() < numTabs-1)
bottomNavigation.setCurrentItem(bottomNavigation.getCurrentItem()+1);
I am developing an app in Android. I am using a flow to take information form the user. To build the flow I am using few fragments. There are five steps and I am using five fragments. I am using another fragment to show the previous records he saved using list view. In my activity I am using a button named Expand. The button Expand is used to show the previous records using fragment. When the user clicks on the button Expand the fragment will take place and the Expand button text will be set to Hide. When the button text is Hide, if the user clicks on the button again the fragment will be removed from the stack and the previous fragment added to the back stack will be shown.
For example let us assume that I have five fragments named FragmentA, FragmentB, FragmentC, FragmentD, FragmentE and another fragment named ProjectRowsFragment which will be used to show the records previously saved in a ListView on the click event of the button named Expand.
Let us assume that the user is in FragmentC and he clicked on the Expand button. What will happen is that FragmentC will be replaced and ProjectRowsFragment will be added. If the user clicks on the button again the ProjectRowsFragment will be replaced and the FragmentC will come in from back stack. If it was FragmentD then it will be replaced and ProjectRowsFragment will be added and if user clicks on the button again ProjectRowsFragment will be replaced and FragmentD will come in from back stack.
I have done with the transactions.
What I want is that I want animation to be added while the ProjectRowsFragment (The fragment I am using to show the records) is shown and replaced. When it is shown it will slide down from the top and then when it is removed from the back stack it will slide up.
After trying a lot I accomplished the slide down effect, but how can I get the slide up animation.
Here is my codes.
fragmentManager = getFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setCustomAnimations(R.animator.slide_in_from_top, 0, R.animator.slide_in_from_bottom, 0);
fragmentTransaction.replace(R.id.fragment_container, ProjectRowsFragment.newInstance(this.projectId));
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
projectRowsExpanded = true;
slide_in_from_top.xml file is
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true" >
<objectAnimator
android:duration="600"
android:propertyName="y"
android:valueFrom="-1280"
android:valueTo="0"
android:valueType="floatType" />
</set>
Here i have three images to visualize
Initial Step
If the user clicks on the button indicated a list will be placed.
If the user clicks again in the indicated button.
Instead of applying custom animations to fragment, you can add animation to your FrameLayout, by passing your fragment container view to following functions to expand and collapse:
FrameLayout v = (FrameLayout) findViewById(R.id.fragment_container);
expand(v); //To Expand
collapse(v); //To Collapse
public static void expand(final View v) {
v.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
final int targetHeight = v.getMeasuredHeight();
v.getLayoutParams().height = 1;
v.setVisibility(View.VISIBLE);
Animation a = new Animation() {
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
v.getLayoutParams().height = interpolatedTime == 1
? ViewGroup.LayoutParams.WRAP_CONTENT
: (int) (targetHeight * interpolatedTime);
v.requestLayout();
}
#Override
public boolean willChangeBounds() {
return true;
}
};
a.setDuration((int) (targetHeight / v.getContext().getResources().getDisplayMetrics().density));
v.startAnimation(a);
}
public static void collapse(final View v) {
final int initialHeight = v.getMeasuredHeight();
Animation a = new Animation() {
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
if (interpolatedTime == 1) {
v.setVisibility(View.GONE);
} else {
v.getLayoutParams().height = initialHeight - (int) (initialHeight * interpolatedTime);
v.requestLayout();
}
}
#Override
public boolean willChangeBounds() {
return true;
}
};
a.setDuration((int) (initialHeight / v.getContext().getResources().getDisplayMetrics().density));
v.startAnimation(a);
}
So I'm using the Sliding Up Panel Library in my application, and I'm trying to implement a ScrollView inside the sliding panel. Since both the sliding panel and the ScrollView are controlled by vertical scrolls, this is causing me some issues.
I've partially got it to work by switching the panel's dragview once the panel has been slid all the way up, and when the ScrollView has been scrolled to the top.
The problem I'm facing now is that, when scrolling the panel to top the scrolling doesn't transfer to the ScrollView, like it does in Google Maps. Little hard to explain, so look at the video here:
www.youtube.com/watch?v=9MUsmQzusX8&feature=youtu.be
This is the panel slide listener:
...
slidePanel.setEnableDragViewTouchEvents(true);
slidePanel.setPanelSlideListener(new SlidingUpPanelLayout.PanelSlideListener() {
#Override
public void onPanelSlide(View panel, float slideOffset) {
// Change the dragview to panelheader when panel is fully expanded
// I'm doing this here instead of in onPanelExpanded,
// because onPanelExpanded first gets called once scroll
// is released.
if (slideOffset <= 0) {
slidePanel.setDragView(layoutPanelTop);
}
// If the panel is not fully expanded set the whole
// panel as dragview
else if(slideOffset > 0) {
slidePanel.setDragView(layoutPanel);
}
}
}
#Override
public void onPanelExpanded(View panel) {
// layout.setDragView(layoutPanelTop);
panelCollapsed = false;
panelExpanded = true;
panelAnchored = false;
Log.v("TAG, "panelExpanded");
}
#Override
public void onPanelCollapsed(View panel) {
slidePanel.setDragView(layoutPanel);
panelCollapsed = true;
panelExpanded = false;
panelAnchored = false;
Log.v(TAG, "panelCollapsed");
}
#Override
public void onPanelAnchored(View panel) {
slidePanel.setDragView(layoutPanel);
panelCollapsed = false;
panelExpanded = false;
panelAnchored = true;
Log.v(TAG, "panelAnchored");
}
});
And I have managed to create a fully working scrollview listener by extending scrollview, which can detect scroll direction and onDown and onUp motion events:
private boolean atScrollViewTop = false;
#Override
public void onScrollChanged(int scrollY) {
scrollY = Math.min(mMaxScrollY, scrollY);
if (scrollY <= 0) {
Log.v("myTag", "You at scrollview top");
atScrollViewTop = true;
} else {
atScrollViewTop = false;
}
mScrollSettleHandler.onScroll(scrollY);
switch (mState) {
case STATE_SCROLL_UP:
if (panelExpanded && atScrollViewTop) {
slidePanel.setDragView(layoutPanel);
} else {
slidePanel.setDragView(layoutPanelTop);
}
Log.v("myTag", "scrolling up");
break;
case STATE_SCROLL_DOWN:
slidePanel.setDragView(layoutPanelTop);
Log.v("myTag", "scrolling down");
break;
}
}
#Override
public void onDownMotionEvent() {
}
#Override
public void onUpOrCancelMotionEvent() {
}
I've been struggling with this the last two days.. So really hope on some pointer at least. Thanks very much in advance. Regards Jakob Harteg.
Sorry for delay.. i find the solution.
image = (ImageView) findViewById(R.id.image); //Layout to slide
SlidingUpPanelLayout layout = (SlidingUpPanelLayout)
findViewById(R.id.sliding_layout);
layout.setDragView(image);
/*This method sets the layout to be used only
in the sliding panel, while all layouts children
are able to perform other functions such as scrolling */
And this is the layout
<..SlidingUpPanelLayout
android:id="#+id/sliding_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center" />
<LinearLayout
android:id="#+id/slide_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="35dp"
android:background="#drawable/ec_image"/>
<!-- FINALLY SCROLLVIEW -->
<ScrollView .... />
Hope it is useful.
I'm guessing ScrollView is child of the SlidingPanel?
In that case, override onInterceptTouchEvent to your SlidingPanel to intercept the onTouch event of your ScrollView when y = 0.
onInterceptTouchEvent does the following two:
child gets action cancel event
parent get the event trough onTouch
I don't know if I've arrived to late but after working hard some days I've found that AndroidSlidingUp panel has a method called setScrollView who handles scroll events properly.
I hope that this post will be useful because I was spending much time searching and I didn't find some tip that help me.