【问题标题】:Displaying PopUpWindow from an other Class - Android显示来自其他类的 PopUpWindow - Android
【发布时间】:2011-12-19 15:15:55
【问题描述】:

基本上,我有两个课程: - 我的活动.java - 其他类.java

MyActivity.java 概述: 那里没有什么真正有趣的...除了 otherClass.java 需要的实例化

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    context       = getApplicationContext()                 ;
    main_activity = this                                    ;
    layout        = (LinearLayout) findViewById(R.id.layout);
    /*
     * Do lot of stuff
     */
}

OtherClasse.java 概述:

它有一个可点击的 TextView。当我进行 LongClick 事件时,我想显示一个 PopUpWindow(在 UI 线程上,所以 MyActivity ...)

view.setOnLongClickListener( new OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        Log.d("TAG", "OnLongClick");
        PopupWindow popup = new PopupWindow(activity.getApplicationContext());
        //tried with new PopupWindow(MyActivity.context);
        popup.setWindowLayoutMode(150, 150);
        popup.setContentView( view );
        //view corresponds to the TextView.
        popup.showAtLocation(MyActivity.layout, Gravity.CENTER_HORIZONTAL, 10, 10);
        return true;
    }
});

日志表明我进入了onLongClick() ... 但是应用崩溃了……

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

但是 MyActivity.layout 是一个静态的 LinearLayout,所以我可以向它添加视图... 关于如何从其他类的 onClickListener 显示 PopUpWindow 的任何建议?


编辑:

@Override
public boolean onLongClick(View v) {
    PopupWindow popup = new PopupWindow(BlaActivity.context);
    TextView tv = new TextView(BlaActivity.context);
    LayoutParams para = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    tv.setLayoutParams(para);
    tv.setText("My future text ...");
    popup.setContentView(tv);
    popup.setWidth(400);
    popup.setHeight(180);
    popup.showAtLocation(tv, Gravity.CENTER_HORIZONTAL, 10, 10);
    popup.update();

    return true;
}

返回一个

android.view.WindowManager$BadTokenException: 无法添加窗口--token null 无效;您的活动正在进行吗?

因为popup.showAtLocation(tv, Gravity.CENTER_HORIZONTAL, 10, 10);在电视上打电话给public IBinder getWindowToken ()……女巫显然没有令牌……

【问题讨论】:

    标签: android onclick popupwindow


    【解决方案1】:

    你在这里引用的视图

    popup.setContentView( view );
    

    可能是问题所在。您每次都创建一个弹出窗口的新实例,但如果您每次都使用相同的文本视图,那么这就是导致 IllegalStateException 的原因。

    以下代码只是一个活动和第二个类。 onLongClick 创建另一个类的实例并调用 showPopUp。

    AnotherClass 的构造函数接受上下文作为参数,稍后用于实例化弹出窗口。

    showPopUp 接受一个视图,该视图用作弹出窗口的父级。

    活动的 onCreate

        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            Button b = (Button)findViewById(R.id.button1);
            final RelativeLayout parent = (RelativeLayout)findViewById(R.id.layout);
            b.setOnLongClickListener( new OnLongClickListener() {
    
                    @Override
                    public boolean onLongClick(View v) {
                        new AnotherClass(getApplicationContext()).showPopUp(parent);
                        return true;
                    }
                });
        }
    

    第二课

    要在 OtherClass 中使用单击/触摸侦听器,您可以像往常一样声明它们,但要在侦听器中创建一个弹出窗口,您需要提供活动的上下文。这样的事情就好了

    public class AnotherClass {
        Context ctx;
        public AnotherClass(Context ctx){
            this.ctx = ctx;
    
            //***EXAMPLE*** wont actually be visible as its not added to a view
            Button b2 = new Button(ctx);
            b2.setText("show popup");
            b2.setOnLongClickListener( new OnLongClickListener() {
    
            @Override
            public boolean onLongClick(View v) {
                showPopUp(v);//View v can be used as the parent
                return true;
            }
        });
        }
    
        public void showPopUp(View parent) {
    
            PopupWindow popup = new PopupWindow(ctx);
            TextView tv = new TextView(ctx);
            LayoutParams para = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
            tv.setLayoutParams(para);
            tv.setText("My future text ...");
            popup.setContentView(tv);
            popup.setWidth(400);
            popup.setHeight(180);
            popup.showAtLocation(parent, Gravity.CENTER_HORIZONTAL, 10, 10);
            popup.update();
        }
    
    }
    

    和xml文件

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent" android:layout_height="fill_parent"
        android:background="@android:color/black" android:id="@+id/layout">
        <Button android:layout_height="wrap_content"
            android:layout_width="wrap_content" android:id="@+id/button1"
            android:text="Button" android:layout_alignParentTop="true"
            android:layout_alignParentLeft="true" android:layout_marginLeft="51dp"
            android:layout_marginTop="28dp"></Button>
    
    </RelativeLayout>
    

    【讨论】:

    • 你有什么建议来解决这个问题?即使使用来自 onLongClick(View v) popup.setContentView( v ); 的视图 ...我仍然有 IllegalStateException
    • 事实上。我只是试图在 PopUpWindow 上显示一些东西......我也尝试过使用之前创建的 textView,它不起作用......请参阅添加的代码。
    • 在您更新的代码中,您在 showAtLocation 中将 textview tv 作为父级传递,但 tv 已经是弹出窗口的子级,我将使用一段适合我的代码编辑我的答案
    • 嗯......它工作正常,谢谢。但实际上,它并不是真正相同的架构。在您的代码中,MainActivity 具有 LongClickListener。但我的架构如下... OtherClass 包含我需要的 textView 和其他属性。解析文档后创建了几个 OtherClass 实例(所以,我在解析的 XML 文档中定义了每个单词 1 个 OtherClass 实例......)然后,MyActivity 只显示了 OtherClass 实例的几个 textView。
    • 那么可以在 OtherClass 中使用 onLongClick 吗?并且仍然在 UI-Thread 中显示弹出窗口?我应该在MyActivity中定义一个静态的LongClickListener,让OtherClass的textView来监听吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-22
    • 2012-02-27
    • 2021-10-17
    • 1970-01-01
    相关资源
    最近更新 更多