Используя тот же onTouchEvent в различные активности
Я использую onTouchEvent
в своем MainActivity.class
. Он работает нормально: если пользователь делает двойной L пальцами, я вызываю фрагмент.
Я хотел бы использовать это onTouchEvent
в другой Activity
но я думаю, что это грязно, если я скопирую весь мой код.
теперь для этого я создал реализацию TouchListenerImpl
для этого :
class TouchListenerImpl implements View.OnTouchListener {
private boolean movingDownL, movingDownR, movingLeft, movingRight, movingSuccessL, movingSuccessR = false;
private Point oldCoordsL, oldCoordsR, startPointL, startPointR = new Point(0, 0);
private boolean admin_touch = false;
private OnLTouch callback;
void setCallback(OnLTouch c) {
callback = c;
}
interface OnLTouch {
void lTouchSuccess();
}
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("debugTouch", "onTouch");
int pIndexL = event.findPointerIndex(event.getPointerId(0));
int pIndexR = 0;
if(event.getPointerCount() > 1) pIndexR = event.findPointerIndex(event.getPointerId(1));
if(event.getPointerCount() > 1 && event.getX(pIndexL) > event.getX(pIndexR)) {
int tmp = pIndexR;
pIndexR = pIndexL;
pIndexL = tmp;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
movingDownL = true;
movingDownR = true;
movingSuccessL = false;
movingSuccessR = false;
if(event.getPointerCount() > 1) {
startPointR = new Point((int) event.getX(pIndexR), (int) event.getY(pIndexR));
oldCoordsR = new Point((int) event.getX(pIndexR), (int) event.getY(pIndexR));
}
startPointL = new Point((int) event.getX(pIndexL), (int) event.getY(pIndexL));
oldCoordsL = new Point((int) event.getX(pIndexL), (int) event.getY(pIndexL));
break;
case MotionEvent.ACTION_MOVE:
int downMinDistance = 300;
int lnrInaccuracy = 10;
int downInaccuracy = 30;
if(event.getPointerCount() > 1) {
if(!movingDownR) {
if(Math.abs(oldCoordsR.x - event.getX(pIndexR)) < downInaccuracy &&
oldCoordsR.y < event.getY(pIndexR)) break;
if(Math.abs(oldCoordsR.y - event.getY(pIndexR)) < lnrInaccuracy &&
oldCoordsR.x > event.getX(pIndexR) && !movingRight) {
movingRight = true;
startPointR = new Point(new Point((int)event.getX(pIndexR), (int)event.getY(pIndexR)));
}
} else {
if (Math.abs(oldCoordsR.x - event.getX(pIndexR)) > downInaccuracy ||
oldCoordsR.y < event.getY(pIndexR)) {
movingDownR = false;
break;
} else if(findDistance(startPointR,
new Point((int)event.getX(pIndexR), (int)event.getY(pIndexR))) >= downMinDistance){
movingDownR = false;
}
}
}
if(!movingDownL) {
if(Math.abs(oldCoordsL.x - event.getX(pIndexL)) < downInaccuracy &&
oldCoordsL.y < event.getY(pIndexL)) break;
if(Math.abs(oldCoordsL.y - event.getY(pIndexL)) < lnrInaccuracy &&
oldCoordsL.x < event.getX(pIndexL) && !movingLeft) {
movingLeft = true;
startPointL = new Point(new Point((int)event.getX(pIndexL), (int)event.getY(pIndexL)));
}
}else {
if (Math.abs(oldCoordsL.x - event.getX(pIndexL)) > downInaccuracy ||
oldCoordsL.y > event.getY(pIndexL)) {
movingDownL = false;
break;
} else if(findDistance(startPointL,
new Point((int)event.getX(pIndexL), (int)event.getY(pIndexL))) >= downMinDistance){
movingDownL = false;
}
}
int lnrMinDistance = 50;
if(movingLeft) {
if (Math.abs(oldCoordsL.y - event.getY(pIndexL)) > lnrInaccuracy ||
oldCoordsL.x > event.getX(pIndexL)) {
movingLeft = false;
break;
} else if(findDistance(startPointL,
new Point((int)event.getX(pIndexL), (int)event.getY(pIndexL))) >= lnrMinDistance) {
movingLeft = false;
movingSuccessL = true;
}
}
if(movingRight) {
if (Math.abs(oldCoordsR.y - event.getY(pIndexR)) > lnrInaccuracy ||
oldCoordsR.x < event.getX(pIndexR)) {
movingRight = false;
break;
} else if(findDistance(startPointR,
new Point((int)event.getX(pIndexR), (int)event.getY(pIndexR))) >= lnrMinDistance) {
movingRight = false;
movingSuccessR = true;
}
}
if(movingSuccessL && movingSuccessR) {
if (!admin_touch)
{
admin_touch = true;
if (callback != null)
callback.lTouchSuccess();
}
}
oldCoordsL = new Point((int)event.getX(pIndexL), (int)event.getY(pIndexL));
oldCoordsR = new Point((int)event.getX(pIndexR), (int)event.getY(pIndexR));
break;
case MotionEvent.ACTION_UP:
movingDownL = false;
movingDownR = false;
movingLeft = false;
movingRight = false;
break;
default:
return false;
}
return true;
}
private double findDistance(Point p1, Point p2) {
return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
}
}
в моей деятельности я называю реализацию так:
public class MainActivity extends AppCompatActivity implements View.OnTouchListener {
TouchListenerImpl imp = new TouchListenerImpl();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imp.setCallback(new TouchListenerImpl.OnLTouch() {
@Override
public void lTouchSuccess() {
Log.d("debugTouch", "WORKING !");
}
});
}
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("debugTouch", "onTouch");
return imp.onTouch(v, event);
}
}
проблема в том, что я никогда не вхожу в свои журналы. Это вообще не работает...
5 ответов
вы можете использовать решение @DrilonBlakqori с небольшими изменениями.
сделать отдельный класс, содержащий общий код, но использовать обратный вызов, чтобы сделать View
видны.
class TouchListenerImpl implements OnTouchListener {
private OnLTouch callback;
@Override
public boolean onTouch(View v, MotionEvent event) {
// all your code
...
if (callback != null)
callback.lTouchSuccess();
...
}
void setCallback(OnLTouch c) {
callback = c;
}
interface OnLTouch {
void lTouchSuccess();
}
}
в своем MainActivity
создать новый экземпляр TouchListenerImpl
и setCallback
как
TouchListenerImpl imp = new TouchListenerImpl();
imp.setCallback(new OnLTouch() {
public void lTouchSuccess() {
frameLayoutAdmin.setVisibility(View.VISIBLE);
getSupportFragmentManager().beginTransaction()
.replace(R.id.framelayout_admin,new AdminLoginFragment())
.commit();
img_close.setVisibility(View.VISIBLE);
}
});
и MainActivity
, the View
на котором вы хотите обнаружить двойной L на View
установите этот слушатель на этом View
.
view.setOnTouchListener(imp);
я предполагаю, что вы хотите обнаружить двойной L на основном плане. Для этого вы можете сделать
findViewById(R.id.mylayout).setOnTouchListener(imp);
надеюсь, это решит вашу проблему.
Вы можете создать действие суперкласса, переопределить onTouchEvent и расширить его. Что-то вроде этого:--3-->
public abstract class BaseActivity extends AppCompatActivity {
@Override
public boolean onTouchEvent(MotionEvent event) {
// Your implementation.
}
}
а затем ваша основная активность:
public class MainActivity extends BaseActivity {
}
вы можете создать суперкласс, который расширяет activity и реализует ваш метод onTouchEvent, и в любом действии вы хотите использовать метод onTouchEvent расширить свой суперкласс. MainActivity также должен был бы расширить его. Или просто расширьте MainActivity в других действиях, где вы хотите использовать метод onTouchEvent.
скопируйте весь свой код вместе с переменными поля в класс, который реализует OnTouchListener
. Тогда просто передайте новый TouchListenerImpl
всякий раз, когда вам это нужно.
class TouchListenerImpl implements OnTouchListener {
// your field variables
@Override
public boolean onTouch(View v, MotionEvent event) {
// all your code
return false;
}
// getters for the variables that you need
}
вам нужно установить прослушиватель в корне действия, и вам нужно сохранить внимание к иерархии представлений. События касания могут использоваться другими представлениями в иерархии, что может быть причиной отсутствия журналов.
Я проверил ваш слушатель с минимальными изменениями, и я получил журналы. Однажды я получил двойной L touch.
public class TouchListenerImpl implements View.OnTouchListener {
private boolean movingDownL, movingDownR, movingLeft, movingRight, movingSuccessL, movingSuccessR = false;
private Point oldCoordsL, oldCoordsR, startPointL, startPointR = new Point(0, 0);
private boolean admin_touch = false;
private OnLTouch callback;
public TouchListenerImpl(OnLTouch callback){
setCallback(callback);
}
void setCallback(OnLTouch c) {
callback = c;
}
public interface OnLTouch {
void lTouchSuccess();
}
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.d("debugTouch", "onTouch");
int pIndexL = event.findPointerIndex(event.getPointerId(0));
int pIndexR = 0;
if(event.getPointerCount() > 1) pIndexR = event.findPointerIndex(event.getPointerId(1));
if(event.getPointerCount() > 1 && event.getX(pIndexL) > event.getX(pIndexR)) {
int tmp = pIndexR;
pIndexR = pIndexL;
pIndexL = tmp;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
movingDownL = true;
movingDownR = true;
movingSuccessL = false;
movingSuccessR = false;
if(event.getPointerCount() > 1) {
startPointR = new Point((int) event.getX(pIndexR), (int) event.getY(pIndexR));
oldCoordsR = new Point((int) event.getX(pIndexR), (int) event.getY(pIndexR));
}
startPointL = new Point((int) event.getX(pIndexL), (int) event.getY(pIndexL));
oldCoordsL = new Point((int) event.getX(pIndexL), (int) event.getY(pIndexL));
break;
case MotionEvent.ACTION_MOVE:
int downMinDistance = 300;
int lnrInaccuracy = 10;
int downInaccuracy = 30;
if(event.getPointerCount() > 1) {
if(!movingDownR) {
if(Math.abs(oldCoordsR.x - event.getX(pIndexR)) < downInaccuracy &&
oldCoordsR.y < event.getY(pIndexR)) break;
if(Math.abs(oldCoordsR.y - event.getY(pIndexR)) < lnrInaccuracy &&
oldCoordsR.x > event.getX(pIndexR) && !movingRight) {
movingRight = true;
startPointR = new Point(new Point((int)event.getX(pIndexR), (int)event.getY(pIndexR)));
}
} else {
if (Math.abs(oldCoordsR.x - event.getX(pIndexR)) > downInaccuracy ||
oldCoordsR.y < event.getY(pIndexR)) {
movingDownR = false;
break;
} else if(findDistance(startPointR,
new Point((int)event.getX(pIndexR), (int)event.getY(pIndexR))) >= downMinDistance){
movingDownR = false;
}
}
}
if(!movingDownL) {
if(Math.abs(oldCoordsL.x - event.getX(pIndexL)) < downInaccuracy &&
oldCoordsL.y < event.getY(pIndexL)) break;
if(Math.abs(oldCoordsL.y - event.getY(pIndexL)) < lnrInaccuracy &&
oldCoordsL.x < event.getX(pIndexL) && !movingLeft) {
movingLeft = true;
startPointL = new Point(new Point((int)event.getX(pIndexL), (int)event.getY(pIndexL)));
}
}else {
if (Math.abs(oldCoordsL.x - event.getX(pIndexL)) > downInaccuracy ||
oldCoordsL.y > event.getY(pIndexL)) {
movingDownL = false;
break;
} else if(findDistance(startPointL,
new Point((int)event.getX(pIndexL), (int)event.getY(pIndexL))) >= downMinDistance){
movingDownL = false;
}
}
int lnrMinDistance = 50;
if(movingLeft) {
if (Math.abs(oldCoordsL.y - event.getY(pIndexL)) > lnrInaccuracy ||
oldCoordsL.x > event.getX(pIndexL)) {
movingLeft = false;
break;
} else if(findDistance(startPointL,
new Point((int)event.getX(pIndexL), (int)event.getY(pIndexL))) >= lnrMinDistance) {
movingLeft = false;
movingSuccessL = true;
}
}
if(movingRight) {
if (Math.abs(oldCoordsR.y - event.getY(pIndexR)) > lnrInaccuracy ||
oldCoordsR.x < event.getX(pIndexR)) {
movingRight = false;
break;
} else if(findDistance(startPointR,
new Point((int)event.getX(pIndexR), (int)event.getY(pIndexR))) >= lnrMinDistance) {
movingRight = false;
movingSuccessR = true;
}
}
if(movingSuccessL && movingSuccessR) {
if (!admin_touch)
{
admin_touch = true;
if (callback != null)
callback.lTouchSuccess();
}
}
oldCoordsL = new Point((int)event.getX(pIndexL), (int)event.getY(pIndexL));
oldCoordsR = new Point((int)event.getX(pIndexR), (int)event.getY(pIndexR));
break;
case MotionEvent.ACTION_UP:
movingDownL = false;
movingDownR = false;
movingLeft = false;
movingRight = false;
break;
default:
return false;
}
return true;
}
private double findDistance(Point p1, Point p2) {
return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
}
}
и использование этого:
public class SplashActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
RelativeLayout layout = (RelativeLayout) findViewById(R.id.activity_splash);
layout.setOnTouchListener(new TouchListenerImpl(new TouchListenerImpl.OnLTouch() {
@Override
public void lTouchSuccess() {
Toast.makeText(getThis(), "L touched!", Toast.LENGTH_SHORT).show();
}
}));
}
public AppCompatActivity getThis(){
return this;
}
}
как я уже сказал, Причина, по которой вы не получаете никаких журналов, может быть вашей иерархия. Убедитесь, что ваши сенсорные события не поглощаются другими видами поверх ваших. Чтобы быть в самой безопасной стороне, вы должны использовать FrameLayout в качестве корневого элемента для такого поведения и булевой переменной, которая позволяет вам решить, следует ли использовать прослушиватель L или нет.
регистрация для дальнейшего использования: https://github.com/fcopardo/EnhancedMapView Если вы проверите файл EnhancedMapView, вы найдете следующее:
public void setOnEnhancedCameraChangeListener(OnEnhancedCameraChangeListener listener){
if(map!=null){
map.setOnCameraChangeListener(camera -> {
if(!isContentTouched() && !isCaptureTouches()){
listener.onCameraChange(camera);
}
});
}
}
Это очень подобно тому, что вы делаете. Я предлагаю вам использовать аналогичный подход, подкласс компоновки фрейма, реализующий ваш L touch listener, а затем использовать такой макет, как корневой класс для ваших представлений и действий. Дай мне знать, если это поможет.