I'm creating a slot machine application and for this I'm using RecycleView as a rail. Therefore all touch\click\scroll events are disabled for RecyclerView.
And to make "spin" I used RecyclerView.fling(...) method since it has better animation.
BUT appearantly fling stops when I touch the recycler view. Why? And how can I disable this?
xml:
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_rail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="#dimen/margin_4"
android:layout_marginStart="#dimen/margin_4"
android:layout_weight="1"
android:padding="#dimen/dp_16"/>
init of RecyclerView:
LinearLayoutManager mRailLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
mRailsBinding.rvRail.setHasFixedSize(true);
new LinearSnapHelper().attachToRecyclerView(mRailsBinding.rvRail);
mRailsBinding.rvRail.setLayoutManager(mRailLayoutManager);
mRailsBinding.rvRail.addOnItemTouchListener(new RecyclerViewDisabler());
mRailsBinding.rvRail.addOnScrollListener(railScrollListener); //checking here for time when scroll ended
mRailsBinding.rvRail.setAdapter(mRailAdapter);
Adapter does nothing special. It just inits views and has no click\touch evenets on them.
RecyclerViewDisabler:
public class RecyclerViewDisabler implements RecyclerView.OnItemTouchListener {
#Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
return true;
}
#Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean state) {}
}
Just read documentation carefull and found solution. I was needed to consume dispatchTouchEvenet manually. See code:
public class UntouchableRecyclerView extends RecyclerView {
public UntouchableRecyclerView(Context context) {
super(context);
}
public UntouchableRecyclerView(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
}
public UntouchableRecyclerView(Context context, #Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return true; //consume
}
}
Related
In some cases, we need to make the RecyclerView cannot scroll, so play to your strengths for this questions.
I have some solutions for this problem, hope it can help you.See below for details:
void setLayoutFrozen (boolean frozen);
I strongly recommend if we only want to inhabit scroll for this scheme for its simplicity and convenience; if you want to know deeply
When we use LayoutManager(LinearManager or GridLayoutManager), we can use this.
`
LinearLayoutManager linearLayoutManager = new
LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, false){
#Override
public boolean canScrollVertically() {
return false;
}
#Override
public boolean canScrollHorizontally() {
return super.canScrollHorizontally();
}
};`
GridLayoutManager is alike.
From above second item, we can extend corresponding LayoutManager.
`
public class MyGridLayoutManager extends GridLayoutManager {
private boolean isScrollEnabled = true;
public MyGridLayoutManager(Context context, int spanCount) {
super(context, spanCount);
}
public MyGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public MyGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {
super(context, spanCount, orientation, reverseLayout);
}
public void setScrollEnabled(boolean flag) {
this.isScrollEnabled = flag;
}
#Override
public boolean canScrollVertically() {
return isScrollEnabled && super.canScrollVertically();
}
}
`
4. We can handle the RecyclerView TouchEvent to achieve the effect.
From above, I believe you can make yourself. Good Luck...
i using facebook ad network for displaying native ads its working fine. So how to implement the event listener for loaded, clicked, error. So i just stuck on that implementation so can any one help me how to do.
listNativeAdsManager = new NativeAdsManager(activity, "mykey", 5)
listNativeAdsManager.setListener(new NativeAdsManager.Listener() {
#Override
public void onAdsLoaded() {
com.facebook.ads.NativeAd fbNative = listNativeAdsManager.nextNativeAd();
fbNative.setAdListener(new AdListener() {
#Override
public void onError(Ad ad, AdError adError) {
Log.d("fb-native","onError ");
}
#Override
public void onAdLoaded(Ad ad) {
Log.d("fb-native","onAdLoaded ");
}
#Override
public void onAdClicked(Ad ad) {
Log.d("fb-native","onAdClicked ");
}
});
View adView = NativeAdView.render(getActivity(), fbNative, NativeAdView.Type.HEIGHT_100);
html_view.addView(adView);
}
#Override
public void onAdError(AdError adError) {
}
});
this is how i implemented but i didn't get any call back from onAdLoaded, onAdClicked so what i have to change
I'm running into the same issues here. As a matter of fact none of the methods is called ever and this is a bug in the Audience SDK!
If you revert back to 4.11.0 you'll get the onAdClicked at least but all versions higher than 4.11.0 won't call any of the callback methods.
There's this bug report open (which a co-worker of mine has filed): https://developers.facebook.com/bugs/158853171214759/.
The solution is simple: don't use the NativeAdsManager but load the ads directly:
final NativeAd nativeAd = new NativeAd(context, facebookNativeAdUnitId);
nativeAd.setAdListener(new AdListener() {
#Override
public void onError(Ad ad, AdError adError) {
}
#Override
public void onAdLoaded(Ad ad) {
}
#Override
public void onAdClicked(Ad ad) {
}
});
nativeAd.loadAd(NativeAd.MediaCacheFlag.ALL);
Here's a possible workaround:
Here's a custom FrameLayout that detects clicks on it:
public class AdContainer extends FrameLayout implements OnGestureListener {
GestureDetector clickDetector;
private NativeAd ad;
private AdListener listener;
public AdContainer(#NonNull Context context) {
super(context);
init();
}
public AdContainer(#NonNull Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public AdContainer(#NonNull Context context, #Nullable AttributeSet attrs, #AttrRes int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
#TargetApi(VERSION_CODES.LOLLIPOP)
public AdContainer(#NonNull Context context, #Nullable AttributeSet attrs, #AttrRes int defStyleAttr, #StyleRes int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
private void init() {
clickDetector = new GestureDetector(getContext(), this);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
clickDetector.onTouchEvent(ev);
return super.onInterceptTouchEvent(ev);
}
public void setAd(NativeAd ad, AdListener listener) {
this.ad = ad;
this.listener = listener;
}
// OnGestureListener
#Override
public boolean onSingleTapUp(MotionEvent e) {
Log.d("AdContainer", "detected a click in an ad container: " + ad);
if ((ad != null) && (listener != null)) {
listener.onAdClicked(ad);
}
return false;
}
#Override
public boolean onDown(MotionEvent e) {
return false;
}
#Override
public void onShowPress(MotionEvent e) {
}
#Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
#Override
public void onLongPress(MotionEvent e) {
}
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
}
Use it like this:
(1) Inflate your ad layout into the new container class:
<com.example.AdContainer
android:id="#+id/ad_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
(2) When binding your ad to the layout, register it with the AdContainer:
AdContainer container = (ViewGroup) findViewById(R.id.ad_container);
container.setAd(ad, this); // make sure the current class implements AdListener
NativeAdsManager listNativeAdsManager = new NativeAdsManager(activity, "mykey", 5);
please not send 5 in parameter of NativeAdsManager 5 is a request number of request send in server at a time so send only 1 in braces like
NativeAdsManager listNativeAdsManager = new NativeAdsManager(activity, "mykey", 1);
this is worked for me...
I want to disable recyclerview scrolling in landscape mode and enable it in the portrait mode.
recyclerView.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() {
#Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
// Stop only scrolling.
return rv.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING;
}
});
I am using this method to disable scrolling but can't find a way to enable it again.
Thanks for any help!
You have to get it done using a custom RecyclerView. Initialize it programmatically when the user is in landscape mode and add this view to your layout:
public class MyRecycler extends RecyclerView {
private boolean verticleScrollingEnabled = true;
public void enableVersticleScroll (boolean enabled) {
verticleScrollingEnabled = enabled;
}
public boolean isVerticleScrollingEnabled() {
return verticleScrollingEnabled;
}
#Override
public int computeVerticalScrollRange() {
if (isVerticleScrollingEnabled())
return super.computeVerticalScrollRange();
return 0;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent e) {
if(isVerticleScrollingEnabled())
return super.onInterceptTouchEvent(e);
return false;
}
public MyRecycler(Context context) {
super(context);
}
public MyRecycler(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
}
public MyRecycler(Context context, #Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
}
For portrait mode keep using your normal RecyclerView.
For this issue, I use this one line solution! :)
myRecyclerView.isNestedScrollingEnabled = false
I have done a lot of search over the topic and have even referred the official documentation from android developer website. But still not clear with the concept.
I have read that for implementing the touch gestures i need to use the GestureDetector and MotionEvent packages. But its implementation kept me confusing over the things.
What i simply want is, my layout includes a many of textviews along with two imageviews. I want to detect a double tap on my images and want to start a new fragment activity. In the new fragment activity i want to show the same image in full screen in landscape mode.
I have done ton of reading but it kept me confusing.
Please help.
Thank you
Here is Double Tap Gesture ImageView.
public class CustomImageView extends ImageView {
private Context context;
private GestureListener mGestureListener;
private GestureDetector mGestureDetector;
public CustomImageView(Context context) {
super(context);
sharedConstructing(context);
}
public CustomImageView(Context context, AttributeSet attrs) {
super(context, attrs);
sharedConstructing(context);
}
public CustomImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
sharedConstructing(context);
}
private void sharedConstructing(Context context) {
super.setClickable(true);
this.context = context;
mGestureListener=new GestureListener();
Log.e("Adding", "Listener:::");
mGestureDetector = new GestureDetector(context, mGestureListener, null, true);
setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
mGestureDetector.onTouchEvent(event);
//..my other code logic
invalidate();
return true; // indicate event was handled
}
});
}
public class GestureListener extends GestureDetector.SimpleOnGestureListener {
#Override
public boolean onDoubleTap( MotionEvent e ) {
// TODO DoubleTap Comparison
Log.e("onDoubleTap","onDoubleTap");
return true;
}
}
}
Reference Link
in my application I have a flipView using the emilsjolander library. It's great, but I can't stop automatically the flipping effect when I open the FlipView. Infact, if I touch the screen the effect stop, but I would stop it after some seconds. Do you know if the library contain a method for it or, alternatively, for simulate the touchEvent after some seconds?
Thank's
I know the answer is so late but it will help others if they stuck in that issue. You can disable automatic flipping on first page by just commenting:
//peakNext(false);
public class MyFlipView extends se.emilsjolander.flipview.FlipView
{
private boolean isEnabled = true;
public MyFlipView(Context context)
{
super(context);
}
public MyFlipView(Context context, AttributeSet attrs)
{
super(context, attrs, 0);
}
public MyFlipView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
if (isEnabled)
return super.onInterceptTouchEvent(ev);
else
return false;
}
public void disable()
{
isEnabled = false;
}
public void enable()
{
isEnabled = true;
}
}
Declare xml as
<"YourPackage".MyFlipView
/>