Я пытаюсь написать приложение, напоминающее программу, которое может добавить виджеты на свой экран.Родительский взгляд не получает событие longpress
Я использую учебник Леонардо Фишера (http://leonardofischer.com/hosting-android-widgets-my-appwidgethost-tutorial/), который является большим.
Для того, чтобы удалить виджет, пользователь должен пропустить Widget, и в этом я столкнулся с некоторыми проблемами; некоторые Виджеты (WhatsApp Messagelist, Evernote List, например) позволяют прокручивать их. По какой-то причине, если вы перечисляете, Android запускает событие LongClick, которое неправомерно удаляет виджет ...
Мой код: (создает виджет и набор LongClickListener)
public void createWidget(Intent data) {
Bundle extras = data.getExtras();
int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
final LauncherAppWidgetHostView hostView = (LauncherAppWidgetHostView) mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);
hostView.setAppWidget(appWidgetId, appWidgetInfo);
// relative layout
//RelativeLayout.LayoutParams lp = new RelativeLayout()
//mainlayout.addView(hostView, lp);
mainlayout.addView(hostView);
// [COMMENTED OUT] hostView.setOnLongClickListener(new AppWidgetLongClickListener(hostView));
}
UPDATE
Бесчисленные часы спустя, я думаю, что частично понял, что происходит, но я все еще не могу получить правильное поведение.
Согласно http://balpha.de/2013/07/android-development-what-i-wish-i-had-known-earlier/, вам нужно реализовать в родительском контейнере в onInterceptTouchEvent
(mainlayout
в моем случае), чтобы перехватывать и обрабатывать события до того, как они достигнут детей (виджеты в моем случае).
Я гугле вверх следующий код и пытался приспособиться к моим потребностям:
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// Consume any touch events for ourselves after longpress is triggered
//Log.i(TAG,"OnIntercept: "+ev.toString());
if (mHasPerformedLongPress) {
Log.i(TAG,"Longpress OK!: "+ev.toString());
mHasPerformedLongPress = false;
return true;
}
// Watch for longpress events at this level to make sure
// users can always pick up this widget
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN: {
postCheckForLongClick();
break;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mHasPerformedLongPress = false;
if (mPendingCheckForLongPress != null) {
removeCallbacks(mPendingCheckForLongPress);
}
break;
}
// Otherwise continue letting touch events fall through to children
return false;
}
class CheckForLongPress implements Runnable {
private int mOriginalWindowAttachCount;
public void run() {
Log.i(TAG,"Inside RUN");
if (getParent()!= null) {
Log.i(TAG,"getParent:"+getParent().toString());
}
if ((getParent() != null) && hasWindowFocus()
&& (mOriginalWindowAttachCount == getWindowAttachCount())
&& !mHasPerformedLongPress) {
if (performLongClick()) { // <-- DOESN'T WORK :(
mHasPerformedLongPress = true;
}
}
}
public void rememberWindowAttachCount() {
mOriginalWindowAttachCount = getWindowAttachCount();
}
}
private void postCheckForLongClick() {
mHasPerformedLongPress = false;
if (mPendingCheckForLongPress == null) {
mPendingCheckForLongPress = new CheckForLongPress();
}
mPendingCheckForLongPress.rememberWindowAttachCount();
postDelayed(mPendingCheckForLongPress, ViewConfiguration.getLongPressTimeout());
}
@Override
public void cancelLongPress() {
super.cancelLongPress();
mHasPerformedLongPress = false;
if (mPendingCheckForLongPress != null) {
removeCallbacks(mPendingCheckForLongPress);
}
}
Приведенный выше код делает перехватывать события прикосновения, когда я нажимаю виджет, но его логика, кажется, направлена на перехват (и направить на дальнейшее лечение) longclicks для виджетов. Мне действительно нужно перехватить longclick внутри родительского представления.
Хитрость, кажется, лежит на if (performLongClick())
, который, насколько я мог бы получить, выстреливает событие LongClick виджету ...
... так что я думаю, мой вопрос в том, как отслеживать длинный клик внутри родительского представления.
Извините за длинный (и, казалось бы, основным) вопрос об обработке событий Android UI, но от того, что я гугла это кажется очень запутанная тема ..
Благодарим за идею, но, как вы можете видеть в моем фрагменте кода, я реализую 'setOnLongClickListener' и из того, что я мог бы изучить,' AppWidgetHostView' не имеет интерфейса для отслеживания событий прокрутки. Можете ли вы указать мне в правильном направлении? – Pbal
Из вашего описания проблемы это звучало так, будто у вас есть прокручиваемый виджет. Если у вас нет прокручиваемого виджета, главный экран может интерпретировать медленное перетаскивание как долгое нажатие, и вы ничего не можете сделать, чтобы его изменить. –
Вы правы; виджеты, такие как «Непрочитанный список WhatsApp» и список Evernote **, прокручивают виджеты **, и всякий раз, когда я просматриваю их, кажется, что «LongClick» уволен. Я проверил исходный код Google Launcher, и он использует почти ту же логику, что и моя (за исключением того, что они обрабатывают несколько экранов, а Launcher моего бедняка - это «только один экран» ...), и этот вид виджетов не генерирует это странное поведение ... Я уверен, что чего-то не хватает, но я не могу понять это. – Pbal