我正在制作一个启动器,我不得不为这些小部件制作一个长时间点击监听器。我创建了一个扩展AppWidgetHost
的类和另一个扩展AppWidgetHostView
的类。他们拦截触摸事件,如果它动作起来,它会看起来并看到动作下降持续400L。除非小部件上没有按钮,否则它可以正常工作。例如,无法长按时钟小部件。
以下是主机视图上longClickListener
的实现:
hostView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
new AlertDialog.Builder(WidgetEdge.this)
.setTitle("Options")
.setMessage("Do you want to delete or resize widget?")
.setIcon(android.R.drawable.sym_def_app_icon)
.setNegativeButton("Delete", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
removeWidget(hostView);
Toast.makeText(WidgetEdge.this, "Widget Deleted", Toast.LENGTH_SHORT).show();
}
})
.setPositiveButton("Resize", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
resizeView(hostView);
}
}).show();
return false;
}
});
以下是AppWidgetHostView
类:
public class LauncherAppWidgetHostView extends AppWidgetHostView{
private LayoutInflater mInflater;
WidgetEdge context;
private OnLongClickListener longClick;
private long down;
public LauncherAppWidgetHostView(Context context) {
super(context);
this.context = (WidgetEdge) context;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public void setOnLongClickListener(OnLongClickListener l) {
this.longClick = l;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean trueOrFalse = false;
switch(ev.getAction()) {
case MotionEvent.ACTION_DOWN:
down = System.currentTimeMillis();
this.getParent().requestDisallowInterceptTouchEvent(true);
trueOrFalse = false;
break;
case MotionEvent.ACTION_UP:
boolean upVal = System.currentTimeMillis() - down > 400L;
if( upVal ) {
longClick.onLongClick(LauncherAppWidgetHostView.this);
trueOrFalse = true;
}
break;
}
return trueOrFalse;
}
@Override
protected View getErrorView() {
return mInflater.inflate(R.layout.appwidget_error, this, false);
}
}
以下是AppWidgetHost
:
import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetProviderInfo;
import android.content.Context;
class LauncherAppWidgetHost extends AppWidgetHost {
LauncherAppWidgetHost(Context context, int hostId) {
super(context, hostId);
}
@Override
protected AppWidgetHostView onCreateView(Context context, int appWidgetId,
AppWidgetProviderInfo appWidget) {
return new LauncherAppWidgetHostView(context);
}
@Override
public void stopListening() {
super.stopListening();
clearViews();
}
}
我尝试使用this link中的代码,但是当我在时钟小部件上进行测试时,它会启动onLongClickListener
两次。此外,当滚动窗口小部件时,如果没有长按,它也会启动onLongClick
。谢谢你的帮助。
- UPDATE-- 我正在使用调试器并发现当使用时钟小部件时,拦截的唯一事件是第一个ACTION_DOWN。之后它从未接受过ACTION_UP。
答案 0 :(得分:0)
如果小部件的行为不像按钮(因此,当无法单击它时),则需要执行更高级的操作来检测长按。
您可以看看https://github.com/willli666/Android-Trebuchet-Launcher-Standalone/blob/master/src/com/cyanogenmod/trebuchet/LauncherAppWidgetHostView.java
如果Apache许可适用于您的项目,则可以复制粘贴整个文件,只需删除getErrorView()
和充气机即可。
这个想法是在检测到初始ACTION_DOWN事件时开始超时,并且当超时触发时,如果视图仍然具有焦点,则可以performLongClick()
。
要实现这一目标要比想象中的难得多,但是至少这对所有小部件都有效,即使那些无法单击的小部件也是如此。