balysv / material-ripple

Android L Ripple effect wrapper for Views
Apache License 2.0
2.36k stars 479 forks source link

Can not work with EditText. #12

Closed mthli closed 9 years ago

mthli commented 9 years ago

I try to add the rippe effect on the EditText just like the Google Search, but the EditText just can not get focus.

balysv commented 9 years ago

The ripple is intercepting all touches, so that happens. I'll have a look

mthli commented 9 years ago

Also can not use with ListView.setOnItemLongClickListener(), it just work as ListView.setOnItemClickListener().

balysv commented 9 years ago

That should be working, as demonstrated in the demo project. Are you using any ListView wrappers or nested layouts in your item view?

mthli commented 9 years ago

Oh I will try again.

Bubumuk commented 9 years ago

LongItemClick doesn't work when using nested layouts?

dinosoeren commented 9 years ago

I'm having the same problem. EditText and Button cannot be focused when inside the MaterialRippleLayout. Is there a way to only intercept the MaterialRippleLayout's immediate child's touch events, instead of intercepting all touch events of all children? For example:

<com.balysv.materialripple.MaterialRippleLayout
    android:id="@+id/ripple"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/transparent"
    android:layout_marginTop="0dp"
    app:rippleOverlay="false"
    app:rippleColor="#ffffff"
    app:rippleHover="true">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello, this is a Button." />

    </LinearLayout>

</com.balysv.materialripple.MaterialRippleLayout>

Is it possible to have the touch event of the MaterialRippleLayout intercept only the touch event of the LinearLayout instead of also intercepting the touch event of the Button?

dinosoeren commented 9 years ago

I've come up with a proposed solution to this bug, after hours of problem-solving. It works great for me.

final LinearLayout card = (LinearLayout) inflater.inflate(R.layout.card, parent, false);
final MaterialRippleLayout ripple = (MaterialRippleLayout) card.findViewById(R.id.ripple);
final Button button = (Button) card.findViewById(R.id.button);
final EditText textBox = (EditText) card.findViewById(R.id.text_box);

ripple.setOnTouchListener(new View.OnTouchListener() {

    // Code for this method adapted from http://stackoverflow.com/a/22486716/3673087
    private boolean viewContains(View view, int rx, int ry) {
        int[] l = new int[2];
        view.getLocationOnScreen(l);
        Rect rect = new Rect(l[0], l[1],
                           l[0] + view.getMeasuredWidth(),
                           l[1] + view.getMeasuredHeight());
        return rect.contains(rx, ry);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        // Here is a great place for code that would normally go in the onClickListener for the
        // MaterialRippleLayout. This can be anything that should be performed onClick.

        if (card != null) {

            // Override child views of the MaterialRippleLayout.

            if(viewContains(textBox, (int) event.getRawX(), (int) event.getRawY())) { 
                textBox.onTouchEvent(event);
            }
            if(viewContains(button, (int) event.getRawX(), (int) event.getRawY())) { 
                button.onTouchEvent(event);
            }

            // Now follow through with the default ripple touch event.
            return ripple.onTouchEvent(event);
        }
        return false;
    }
});
dinosoeren commented 9 years ago

UPDATE: My previous fix doesn't seem to work with EditText views with android:inputType="textMultiLine". The .getMeasuredHeight() and .getHeight() methods don't seem to be accurate on these views. Any suggestions?

balysv commented 9 years ago

I've added some experimental logic of intercepting touch events that might fix your issues and allow any number of nested layout within MaterialRippleLayout. You can even nest a ripple inside a ripple as long as they are wrapped by some layout :)

balysv commented 9 years ago

You can get the new version through

repositories {
    maven {
        url "https://oss.sonatype.org/content/repositories/snapshots/"
    }
}

compile 'com.balysv:material-ripple:0.9.6-SNAPSHOT@aar'

Or wait until I upload it to Central