background
I have a viewPager and a tabHost which are used to navigate between pages.
On some cases , the fragment within the viewPager would want to disallow navigating , and even show a dialog to ask the user to verify that the changes that were done in the fragment will be canceled .
If the user confirmed , I would allow navigating , and if not , I would disallow it.
The problem
I need to get notified when the user attempts to navigate to another tab , and (under some conditions i've created) disallow/allow it .
What I've tried
The only functionality i've found is how to disable the switching .
for viewPager , i use :
mViewPager.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(final View v, final MotionEvent event) {
return !mIsTabsSwitchingEnabled;
}
});
and for the tabHost , i use:
mTabHost.getTabWidget().setEnabled(mIsTabsSwitchingEnabled);
However , what i need is quite different - i need to capture the event of starting to navigate , and be able to tell it if i allow it or not .
The question
How should i solve this problem ?
How can i get notified when starting to navigate , and cancel it if needed ?
You should use TabTabHost.OnTabChangeListener
ok , i've solved it for now by using the next code , which i hope that it covers everything .
if anyone can think of another solution that might be better , please write it down .
final OnTouchListener onTouchListener = new OnTouchListener() {
#Override
public boolean onTouch(final View v, final MotionEvent event) {
return isCurrentFragmentNeedTabSwitchingBlocking();
}
};
mViewPager.setOnTouchListener(onTouchListener);
for (int i = 0; i < mTabHost.getTabWidget().getChildCount(); ++i)
mTabHost.getTabWidget().getChildAt(i).setOnTouchListener(tabOnTouchListener);
Related
Let's say:
Activity1 contains some items which will be dragged
Activity2 contains some "boxes" which will be filled with Activity1's item. The boxes already have drag listener.
I want to drag item from Activity1 into Activity2
I tried these method:
I implement onLongClickListener() on Activity1 items and use startDrag() there. Then I open Activity2. I could make the drag shadow appear but the boxes cannot receive the item. In fact, they doesn't respond to any DragEvent.
I implement onLongClickListener() on Activity1 items, but only to pass the data into Activity2. Then I use startDrag() when Activity2 start(specifically in onResume()). Here, the shadow not appear and the boxes doesn't respond to any DragEvent.
Is there any way to make this possible?
its possible using two fragment of view pager instead of 2 activity and you can set logic of drag and drop in onTouch() or dispatchTouch().
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return super.dispatchTouchEvent(ev);
}
using dispatchTouch() in activity of fragment or
viewPager.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}
});
using touch event of view pager you can set drag and drop logic within inside.
I hope this idea can help you.
I call this function in my activity :
#Override
public boolean dispatchTouchEvent(MotionEvent touchEvent)
That allows me to process action before any components get focused or even deny the focus to these elements.
PROBLEM : I was wondering how I could know what component (View) has been touched in this function, then I could choose if I want to consumme the event or not.
UGLY SOLUTION : I'm currently having an ugly solution which is : I know the position of the component that is allowed to get the event, and I do a plenty of condition to approximately decide if the user clicked on this component.
Thanks.
You probably want to use the OnTouchListener
private OnTouchListener mOnTouchListener= new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch(v.getId()){
case R.id.id1):
// Do stuff
break;
case R.id.id2:
// Do stuff
break;
}
return false/true;
}
};
view.getid==R.id.//id in layout// condition can be checked for the required view is clicked
i am using listview in android with ratingbar as well as check box, here is my problem,if i am setting onitemclick listner to the listview, it is not working?
Please any one can help me..
Thanks in advance.
In your xml file.............
In checkbox..........
android:focusable="false"
Yes, I see the exact same thing. If you remove the checkbox and rating bar, then OnItemClick works, but with these widgets in your view, Android thinks the user wants to interact with them.
So instead you have to handle the user click in the view itself (rather than the listview).
OnTouchListener pressItemListener =new OnTouchListener()
{
#Override
public boolean onTouch(View arg0, MotionEvent arg1)
{
HomeActivity ha = (HomeActivity) getContext();
ha.handleLocationTouchEvent(position, arg1);
return false;
}
}
newView.setOnTouchListener(pressItemListener);
In the above example, HomeActivity is my parent activity. So I handle the user touch event in the custom view and then pass it off to the parent activity where you can do with it what you want. You might also want to handle onLongTouch. Hope this helps.
I one activity I am seting different layouts depends on user choice.
For example I have setContentView(R.layout.main),
after that when user choose something I am setting new like setContentView(R.layout.first) when next time clicks I am setting setContentView(R.layout.second).
I need to change content in same activity. How to set animation ( something like when I really changing between activities ) when I changes content from main to first and from first to second ?
Let us take this with example.
Suppose we are changing view on press of button,
private OnTouchListener touch = new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
loadOutViewAnimation();//
loadInViewAnimation();
}
}
}
public void loadOutViewAnimation(){
//considering layout is your root layout
layout.setAnimation(animation);
}
public void loadInViewAnimation(){
setContentView(R.layout.first);
//by using findview by id here you will get root layout.
layout.setAnimation(animation);
}
You can do this by using ViewFlipper.....
See this example http://www.androidpeople.com/android-viewflipper-example
I hope this will help you to solve your problem.
You can used methods from AnimationUtils class makeInAnimation(context, boolean) and makeOutAnimation(context, boolean) to create Animation object. Config it with setStartTime and setDuration methods. Now you can call setAnimation on your view and it will be appearing or/and disappearing with your animation.
Using a widget.Gallery to display a horizontally scrolling list of items. I've implemented paging in the gallery with what seems to be the standard technique: subclass Gallery and implement:
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if (velocityX>0) {
onKeyDown(KeyEvent.KEYCODE_DPAD_LEFT, null);
} else {
onKeyDown(KeyEvent.KEYCODE_DPAD_RIGHT, null);
}
}
When tapping the gallery, I fade up next and previous image buttons. When clicking these, I want the gallery to animated to the next/previous page, respectively. I've tried calling onKeyDown from my next-button handler, but strangely this has no effect.
AbsSpinner has setSelection(int position, boolean animate) but animate is ignored in Gallery.
Exactly what toucan said, but to elaborate further (comments limits are too short):
The problem seems to be the fact that the Gallery doesn't let the user scroll if no children exist in that position yet. scrollToChild() is the culprit when trying to inject the event:
private boolean scrollToChild(int childPosition) {
View child = getChildAt(childPosition);
if (child != null) {
int distance = getCenterOfGallery() - getCenterOfView(child);
mFlingRunnable.startUsingDistance(distance);
return true;
}
return false;
}
Interestingly, if you fling the gallery with your fingers, it will cause the child to be created. Then, if you let go of your finger (going back to the original position), and then press the button that activates the onKeyDown injection, it will work flawlessly - because the child is there.
Unfortunately there's no real solution since everything is private in that class. The only solution is to use setSpacing(-1) or something in the gallery, so left and right children are always created and visible, but just behind the currently selected view.
As a footnote, I'm really baffled as to why everything is private in that class (or in any other of the Android widget classes for that matter). This is one of those things that could easily be fixed with some small code change.
Edit (Aug 2012): For future reference, rather than trying to use a Gallery for this kind of pattern (when you want the user to swipe between different items while only one of them is visible), it's much better to use the Android's compatibility package's ViewPager class. In my opinion, the compatibility package is not as celebrated as it should be (it took me a while to get notice of it). For developers targeting Android 2.x+, it's a godsend.
this is working
create 2 image buttons and gallery
eg:
nextbtn,backbtn and gall
button code is avialable here
nextbtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
gall.onKeyDown(KeyEvent.KEYCODE_DPAD_RIGHT, null);
}
});
backbtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
gall.onKeyDown(KeyEvent.KEYCODE_DPAD_LEFT, null);
}
});
String strMethod = velocityX > 0 ? "movePrevious" : "moveNext";
try {
Method method = Gallery.class.getDeclaredMethod(strMethod, null);
method.setAccessible(true);
method.invoke(this, null);
} catch (Exception e) {
e.printStackTrace();
}