繁体   English   中英

如何为 AppWidgetHostView 制作长按侦听器

[英]How can I make a long click listener for an AppWidgetHostView

我正在制作一个启动器,但我一直在为小部件制作一个长按监听器。 我创建了一个扩展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();
    }
}

我曾尝试使用此链接中的代码,但是当我在时钟小部件上进行测试时,它onLongClickListener两次启动onLongClickListener 此外,当小部件滚动时,无需长按,它也会启动onLongClick 谢谢你的帮助。

--UPDATE-- 我正在使用调试器,发现在使用时钟小部件时,截获的唯一事件是第一个 ACTION_DOWN。 在那之后,它再也没有拿起 ACTION_UP。

如果小部件的行为不像按钮(所以当它不能被点击时)你需要做一些更高级的事情来检测长点击。

您可以查看https://github.com/willli666/Android-Trebuchet-Launcher-Standalone/blob/master/src/com/cyanogenmod/trebuchet/LauncherAppWidgetHostView.java如果 Apache 许可证适用于您的项目,您可以复制粘贴整个文件,您只需要删除getErrorView()和充气器就可以了。

这个想法是在检测到初始 ACTION_DOWN 事件时开始超时,当超时触发时,如果视图仍然有焦点,那么你可以performLongClick()

这比人们预期的要困难得多,但至少这适用于所有小部件,即使是那些无法点击的小部件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM