mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-19 04:05:36 +00:00
custom touch listener for views in ViewPager
This commit is contained in:
@@ -1,106 +1,110 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
android:id="@+id/race_content_header"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/sap_gray">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/timer_text"
|
||||
<com.sap.sailing.racecommittee.app.ui.layouts.TimePanelHeaderLayout
|
||||
android:id="@+id/race_content_header"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/side_padding"
|
||||
android:layout_marginRight="@dimen/side_padding"
|
||||
android:layout_marginTop="@dimen/header_margin_top"
|
||||
android:gravity="center"
|
||||
android:singleLine="true"
|
||||
android:textColor="?attr/white"
|
||||
android:textSize="@dimen/panel_button_header_size"
|
||||
tools:text="@string/time"/>
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/sap_gray">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/time_marker"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/thin_line"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:src="?attr/marker"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@id/time_marker"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginBottom="@dimen/side_padding"
|
||||
android:baselineAligned="false">
|
||||
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/start_time_container"
|
||||
android:layout_width="wrap_content"
|
||||
<TextView
|
||||
android:id="@+id/timer_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/time_start"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toRightOf="@+id/linked_locked_area"
|
||||
android:textColor="?attr/white"
|
||||
android:textSize="@dimen/panel_button_caption_size"
|
||||
tools:text="@string/time_start"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/linked_locked_area"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginRight="6dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/time_start_lock"
|
||||
android:layout_width="@dimen/side_button_lockSize"
|
||||
android:layout_height="@dimen/side_button_lockSize"
|
||||
android:src="?attr/lock_outline"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/linked_race"
|
||||
android:layout_width="@dimen/side_button_lockSize"
|
||||
android:layout_height="@dimen/side_button_lockSize"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:src="?attr/link_24dp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="@dimen/side_padding"
|
||||
android:layout_toRightOf="@+id/start_time_container">
|
||||
android:layout_marginRight="@dimen/side_padding"
|
||||
android:layout_marginTop="@dimen/header_margin_top"
|
||||
android:gravity="center"
|
||||
android:singleLine="true"
|
||||
android:textColor="?attr/white"
|
||||
android:textSize="@dimen/panel_button_header_size"
|
||||
tools:text="@string/time"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/current_time"
|
||||
<ImageView
|
||||
android:id="@+id/time_marker"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/thin_line"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:src="?attr/marker"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_above="@id/time_marker"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginBottom="@dimen/side_padding"
|
||||
android:baselineAligned="false">
|
||||
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/start_time_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:drawableLeft="?attr/access_time_18dp"
|
||||
android:drawablePadding="6dp"
|
||||
android:gravity="center"
|
||||
android:textColor="?attr/white"
|
||||
android:textSize="@dimen/panel_button_caption_size"
|
||||
android:visibility="invisible"
|
||||
tools:text="@string/time"
|
||||
tools:visibility="visible"/>
|
||||
</RelativeLayout>
|
||||
android:layout_centerVertical="true">
|
||||
|
||||
</RelativeLayout>
|
||||
<TextView
|
||||
android:id="@+id/time_start"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toRightOf="@+id/linked_locked_area"
|
||||
android:textColor="?attr/white"
|
||||
android:textSize="@dimen/panel_button_caption_size"
|
||||
tools:text="@string/time_start"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/linked_locked_area"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginRight="6dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/time_start_lock"
|
||||
android:layout_width="@dimen/side_button_lockSize"
|
||||
android:layout_height="@dimen/side_button_lockSize"
|
||||
android:src="?attr/lock_outline"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/linked_race"
|
||||
android:layout_width="@dimen/side_button_lockSize"
|
||||
android:layout_height="@dimen/side_button_lockSize"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:src="?attr/link_24dp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"/>
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="@dimen/side_padding"
|
||||
android:layout_toRightOf="@+id/start_time_container">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/current_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:drawableLeft="?attr/access_time_18dp"
|
||||
android:drawablePadding="6dp"
|
||||
android:gravity="center"
|
||||
android:textColor="?attr/white"
|
||||
android:textSize="@dimen/panel_button_caption_size"
|
||||
android:visibility="invisible"
|
||||
tools:text="@string/time"
|
||||
tools:visibility="visible"/>
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
</com.sap.sailing.racecommittee.app.ui.layouts.TimePanelHeaderLayout>
|
||||
</RelativeLayout>
|
||||
+8
-4
@@ -28,6 +28,7 @@ import com.sap.sailing.racecommittee.app.R;
|
||||
import com.sap.sailing.racecommittee.app.data.DataManager;
|
||||
import com.sap.sailing.racecommittee.app.domain.ManagedRace;
|
||||
import com.sap.sailing.racecommittee.app.ui.fragments.raceinfo.StartTimeFragment;
|
||||
import com.sap.sailing.racecommittee.app.ui.layouts.TimePanelHeaderLayout;
|
||||
import com.sap.sailing.racecommittee.app.utils.RaceHelper;
|
||||
import com.sap.sailing.racecommittee.app.utils.TickSingleton;
|
||||
import com.sap.sailing.racecommittee.app.utils.TimeUtils;
|
||||
@@ -43,7 +44,7 @@ public class TimePanelFragment extends BasePanelFragment {
|
||||
private IntentReceiver mReceiver;
|
||||
private SimpleDateFormat dateFormat;
|
||||
|
||||
private View mRaceHeader;
|
||||
private TimePanelHeaderLayout mRaceHeader;
|
||||
private View mTimeLock;
|
||||
private TextView mCurrentTime;
|
||||
private TextView mHeaderTime;
|
||||
@@ -69,9 +70,12 @@ public class TimePanelFragment extends BasePanelFragment {
|
||||
mStateListener = new RaceStateChangedListener();
|
||||
|
||||
mRaceHeader = ViewHelper.get(layout, R.id.race_content_header);
|
||||
if (mRaceHeader != null) {
|
||||
mRaceHeader.setOnClickListener(new RaceHeaderClick());
|
||||
}
|
||||
mRaceHeader.setRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
new RaceHeaderClick().onClick(null);
|
||||
}
|
||||
});
|
||||
|
||||
mTimeLock = ViewHelper.get(layout, R.id.time_start_lock);
|
||||
mCurrentTime = ViewHelper.get(layout, R.id.current_time);
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package com.sap.sailing.racecommittee.app.ui.layouts;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.sap.sailing.racecommittee.app.ui.utils.TouchEventListener;
|
||||
|
||||
public class TimePanelHeaderLayout extends RelativeLayout {
|
||||
|
||||
private TouchEventListener mTouchEventListener;
|
||||
|
||||
public TimePanelHeaderLayout(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public TimePanelHeaderLayout(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public TimePanelHeaderLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
|
||||
mTouchEventListener = new TouchEventListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (mTouchEventListener != null) {
|
||||
return mTouchEventListener.onTouchEvent(event);
|
||||
} else {
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
public void setRunnable(Runnable clickRunnable) {
|
||||
if (mTouchEventListener != null) {
|
||||
mTouchEventListener.setClickRunnable(clickRunnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
package com.sap.sailing.racecommittee.app.ui.utils;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import android.support.v4.view.ViewConfigurationCompat;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
public class TouchEventListener {
|
||||
|
||||
private WeakReference<View> mView;
|
||||
private Runnable mClickRunnable;
|
||||
private float mStartX;
|
||||
private float mStartY;
|
||||
private boolean mInXRange;
|
||||
private boolean mInYRange;
|
||||
private int mTouchSlop;
|
||||
private boolean mEnabled;
|
||||
|
||||
public TouchEventListener(View view) {
|
||||
mView = new WeakReference<>(view);
|
||||
|
||||
final ViewConfiguration configuration = ViewConfiguration.get(view.getContext());
|
||||
mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
|
||||
|
||||
mEnabled = true;
|
||||
}
|
||||
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
int action = event.getActionMasked();
|
||||
View view = mView.get();
|
||||
|
||||
if (view == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
mInXRange = true;
|
||||
mInYRange = true;
|
||||
view.getParent().requestDisallowInterceptTouchEvent(true);
|
||||
mStartX = event.getX();
|
||||
mStartY = event.getY();
|
||||
return true;
|
||||
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
boolean inLimit = false;
|
||||
if (mInXRange) {
|
||||
inLimit = Math.abs(event.getX() - mStartX) <= mTouchSlop;
|
||||
mInXRange = inLimit;
|
||||
} else {
|
||||
view.getParent().requestDisallowInterceptTouchEvent(false);
|
||||
}
|
||||
if (mInYRange) {
|
||||
mInYRange = Math.abs(event.getY() - mStartY) <= mTouchSlop;
|
||||
}
|
||||
return inLimit;
|
||||
|
||||
case MotionEvent.ACTION_UP:
|
||||
view.getParent().requestDisallowInterceptTouchEvent(false);
|
||||
if (mInXRange && mEnabled) {
|
||||
if (mClickRunnable != null) {
|
||||
mClickRunnable.run();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setClickRunnable(Runnable runnable) {
|
||||
mClickRunnable = runnable;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
mEnabled = enabled;
|
||||
}
|
||||
}
|
||||
+30
-63
@@ -6,18 +6,17 @@ import android.content.res.TypedArray;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.support.v4.view.ViewConfigurationCompat;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.sap.sailing.racecommittee.app.R;
|
||||
import com.sap.sailing.racecommittee.app.ui.utils.TouchEventListener;
|
||||
import com.sap.sailing.racecommittee.app.utils.ThemeHelper;
|
||||
|
||||
public class PanelButton extends FrameLayout implements DialogInterface.OnClickListener {
|
||||
@@ -40,13 +39,8 @@ public class PanelButton extends FrameLayout implements DialogInterface.OnClickL
|
||||
|
||||
private int mType;
|
||||
|
||||
private Runnable mClickRunnable;
|
||||
private float mStartX;
|
||||
private boolean mUseThis;
|
||||
private int mTouchSlop;
|
||||
private boolean mClickEnabled;
|
||||
|
||||
private PanelButtonClick mListener;
|
||||
private TouchEventListener mTouchEventListener;
|
||||
|
||||
public PanelButton(Context context) {
|
||||
this(context, null);
|
||||
@@ -61,6 +55,31 @@ public class PanelButton extends FrameLayout implements DialogInterface.OnClickL
|
||||
|
||||
final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PanelButton);
|
||||
|
||||
Runnable clickRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mLock != null && mLock.getVisibility() == VISIBLE && isNormal()) {
|
||||
if (mType == 2 && mSwitch != null) {
|
||||
mSwitch.setChecked(!mSwitch.isChecked());
|
||||
}
|
||||
showChangeDialog(PanelButton.this);
|
||||
} else {
|
||||
if (mType == 2) {
|
||||
if (mListener != null && mSwitch != null) {
|
||||
mListener.onChangedSwitch(PanelButton.this, mSwitch.isChecked());
|
||||
}
|
||||
} else {
|
||||
if (mListener != null) {
|
||||
mListener.onClick(PanelButton.this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
mTouchEventListener = new TouchEventListener(this);
|
||||
mTouchEventListener.setClickRunnable(clickRunnable);
|
||||
|
||||
setPanelType(a.getInt(R.styleable.PanelButton_buttonType, 0));
|
||||
|
||||
switch (mType) {
|
||||
@@ -93,31 +112,6 @@ public class PanelButton extends FrameLayout implements DialogInterface.OnClickL
|
||||
a.recycle();
|
||||
|
||||
setMarkerLevel(LEVEL_NORMAL);
|
||||
|
||||
mClickRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mLock != null && mLock.getVisibility() == VISIBLE && isNormal()) {
|
||||
if (mType == 2 && mSwitch != null) {
|
||||
mSwitch.setChecked(!mSwitch.isChecked());
|
||||
}
|
||||
showChangeDialog(PanelButton.this);
|
||||
} else {
|
||||
if (mType == 2) {
|
||||
if (mListener != null && mSwitch != null) {
|
||||
mListener.onChangedSwitch(PanelButton.this, mSwitch.isChecked());
|
||||
}
|
||||
} else {
|
||||
if (mListener != null) {
|
||||
mListener.onClick(PanelButton.this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
final ViewConfiguration configuration = ViewConfiguration.get(context);
|
||||
mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
|
||||
}
|
||||
|
||||
public void setListener(PanelButtonClick listener) {
|
||||
@@ -150,11 +144,11 @@ public class PanelButton extends FrameLayout implements DialogInterface.OnClickL
|
||||
mType = type;
|
||||
switch (type) {
|
||||
case 2:
|
||||
mClickEnabled = false;
|
||||
mTouchEventListener.setEnabled(false);
|
||||
break;
|
||||
|
||||
default:
|
||||
mClickEnabled = true;
|
||||
mTouchEventListener.setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -346,34 +340,7 @@ public class PanelButton extends FrameLayout implements DialogInterface.OnClickL
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
int action = event.getActionMasked();
|
||||
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
mUseThis = true;
|
||||
getParent().requestDisallowInterceptTouchEvent(true);
|
||||
mStartX = event.getX();
|
||||
return true;
|
||||
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
boolean inLimit = false;
|
||||
if (mUseThis) {
|
||||
inLimit = Math.abs(event.getX() - mStartX) <= mTouchSlop;
|
||||
mUseThis = inLimit;
|
||||
} else {
|
||||
getParent().requestDisallowInterceptTouchEvent(false);
|
||||
}
|
||||
return inLimit;
|
||||
|
||||
case MotionEvent.ACTION_UP:
|
||||
getParent().requestDisallowInterceptTouchEvent(false);
|
||||
if (mUseThis && mClickEnabled) {
|
||||
performClick();
|
||||
mClickRunnable.run();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return mTouchEventListener.onTouchEvent(event);
|
||||
}
|
||||
|
||||
public interface PanelButtonClick {
|
||||
|
||||
Reference in New Issue
Block a user