【问题标题】:image view on Customized dialog box自定义对话框上的图像视图
【发布时间】:2012-11-21 11:50:55
【问题描述】:

我在 android 中的自定义对话框有一个问题,我在 android 中使用 javainterface 创建了自定义对话框,在我的类 CustomizeDialog 中,我有一个线程在后台执行一些处理,之后我为此自定义对话框设置了一个 imgae我在 OnPostExecute 中设置了图像,但出现以下错误

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

我知道我们无法从另一个线程访问主 ui,但我们在 OnPostExecuted 中访问主 ui 在我的情况下也无法正常工作, 在我的另一个类(main.class)中,我将调用这个类

CustomizeDialog customizeDialog = new CustomizeDialog(mContext);
customizeDialog.show();

这是我创建对话框的代码

public class CustomizeDialog extends Dialog implements OnClickListener {
Button okButton;
ImageView img = null;
ImageView img2=null;
ImageView img3 = null;
ImageView img4= null;
 Bitmap bm;

public CustomizeDialog(Context context) {
super(context);

img2 = (ImageView) findViewById(R.id.imageView1);
img3 = (ImageView) findViewById(R.id.imageView3);
img4 = (ImageView) findViewById(R.id.imageView4);

WindowManager.LayoutParams params = getWindow().getAttributes();  
params.x = 30;  
params.height = 500;  
params.width = 500;  
params.y = 50;  

this.getWindow().setAttributes(params);  

setContentView(R.layout.test);
img = (ImageView) findViewById(R.id.imageView2);

img.setBackgroundResource(R.drawable.sample);

AnimationDrawable frameAnimation = (AnimationDrawable) img.getBackground();

 //Start the animation (looped playback by default).
 frameAnimation.start();

new LongOperation1(context).execute("");

}

else
{
    Toast toast = Toast.makeText(getContext(), "Erorr",
            Toast.LENGTH_SHORT);
    toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
    toast.show();
} }

private class LongOperation1 extends AsyncTask<String, String, String> {

    @Override
    protected String doInBackground(String... params) {
     //here i do some process
    return "Executed";
    }

    @Override
    protected void onPostExecute(String result) {

                 // here i do some process to get bm

            img2.setImageBitmap(bm);
            }

    @Override
    protected void onPreExecute() {
    }
    @Override
    protected void onProgressUpdate(String... values) {
        }
}

AndroidHTMLActivity 类

    package com.example.hellogap;
import com.example.javainterface.R;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.os.Bundle;
import android.view.Gravity;
import android.webkit.WebView;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class AndroidHTMLActivity extends Activity {

WebView myBrowser;
private static final int TEXT_ID = 0;
 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.main);
     myBrowser = (WebView)findViewById(R.id.mybrowser);
     myBrowser.addJavascriptInterface(new MyJavaScriptInterface(this), "AndroidFunction");

     myBrowser.getSettings().setJavaScriptEnabled(true);
     myBrowser.loadUrl("file:///android_asset/mypage.html");

 }

public class MyJavaScriptInterface {
 Context mContext;

    MyJavaScriptInterface(Context c) {
        mContext = c;
    }

    public void showToast(String toast){
        Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
    }

    public void openAndroidDialog(){
        //CustomizeDialog.this.img2.setImageBitmap(bm);

        CustomizeDialog customizeDialog = new CustomizeDialog(AndroidHTMLActivity.this);
        customizeDialog.show();


    }

}
}

test.xml

     <AbsoluteLayout
         xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/widget0"
         android:layout_width="500dp"
         android:layout_height="520dp"

         android:background="@drawable/bg"
         android:clickable="false" >

         <ImageView
             android:id="@+id/imageView3"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_x="193dp"
             android:layout_y="315dp"
             android:src="@drawable/fb" />

         <ImageView
             android:id="@+id/imageView1"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_x="51dp"
             android:layout_y="318dp"
             android:src="@drawable/fa" />

         <ImageView
             android:id="@+id/imageView4"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_x="335dp"
             android:layout_y="316dp"
             android:src="@drawable/fc" />

         <ImageView
             android:id="@+id/imageView2"
             android:layout_width="200dp"
             android:layout_height="204dp"
             android:layout_x="298dp"
             android:layout_y="91dp" />

     </AbsoluteLayout>

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   >
<TextView 
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"

   />
<WebView
   android:id="@+id/mybrowser"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
  />
</LinearLayout>

mypage.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width; user-scalable=0;" />
<title>My HTML</title>
</head>
<body>
<h1>MyHTML</h1>

<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" />

<script type="text/javascript">
 function showAndroidToast(toast) {
     AndroidFunction.showToast(toast);
 }
</script>

<input type="button" value="Open Dialog" onClick="openAndroidDialog()" />

<script type="text/javascript">
 function openAndroidDialog() {
     AndroidFunction.openAndroidDialog();
 }
</script>

</body>
</html>

有没有人知道如何做到这一点

【问题讨论】:

  • 你是在UI线程中调用customizedDialog.show()方法吗?
  • 不,我会在另一堂课上调用这个
  • 尝试确保 show() 调用发生在 UI 线程中(例如,您可以使用 Activity.runOnUiThread())。如果调用它的类正在后台线程中使用,它可能会抛出该错误。
  • 您是否在使用 tabhost 进行此活动?
  • 我为什么选择标签布局,我的问题是异步任务

标签: android android-layout android-asynctask imageview android-alertdialog


【解决方案1】:

编辑

如果我很好理解您要做什么,请用以下代码替换您的代码:

CustomizeDialog.java

import android.app.Dialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;

public class CustomizeDialog extends Dialog {

    Button okButton;
    ImageView imageAnim = null;

    Bitmap bm;

    Context ctx;

    AnimationDrawable frameAnimation;

    public CustomizeDialog(Context context) {
        super(context);     

        ctx = context;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);     


        WindowManager.LayoutParams params = getWindow().getAttributes();  
        params.x = 30;  
        params.height = 500;  
        params.width = 500;  
        params.y = 50;  

        getWindow().setAttributes(params);  

        setContentView(R.layout.test);

        frameAnimation =  new AnimationDrawable(); 

        frameAnimation.addFrame(ctx.getResources().getDrawable(R.drawable.fb1), 1000);
        frameAnimation.addFrame(ctx.getResources().getDrawable(R.drawable.fb2), 1000);
        frameAnimation.addFrame(ctx.getResources().getDrawable(R.drawable.fb3), 1000);
        frameAnimation.addFrame(ctx.getResources().getDrawable(R.drawable.fb4), 1000);

        // set false for loop animation
        frameAnimation.setOneShot(false);

        imageAnim = (ImageView) findViewById(R.id.img); 
        imageAnim.setBackgroundDrawable(frameAnimation);

        imageAnim.post(new Starter()); 

    }

    class Starter implements Runnable { 

        public void run() { 
            frameAnimation.start(); 
        } 

    } 
}

文本.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Gallery animated" />

    <ImageView
        android:id="@+id/img"
        android:layout_width="154dp"
        android:layout_height="217dp" />

</LinearLayout>

此代码显示一个对话框,其中每秒加载 4 张图像(循环中)。有用。 顺便说一句,你的代码有很多问题。

1) 首先,你必须在 setContentView 之后而不是之前放置对 xml 布局的变量引用!

2) 当您执行 AnimationDrawable frameAnimation = (AnimationDrawable) img.getBackground() 时,您不能将 AnimationDrawable 转换为 BitmapDrawable p>

3) 我不明白您为什么尝试使用 NULL 位图变量设置 img.setImageBitmap(bm)bm 从未设置)。

4) 你必须在 onCreate 方法中初始化 contentView,而不是在 CustomDialog 构造函数中。

5) 您必须使用 Thread 才能不停止 UI 加载。如果将动画循环放在代码对话框创建中,对话框可能会停止并无法正确显示。

希望对你有所帮助

【讨论】:

  • 请发布 xml 布局内容,以便我可以在我的 Eclipse 中重新创建项目和错误
  • 实际上加载正常工作的动画没有问题,而且我在后台做了一些处理,请查看我之前的代码 AsyncTask (LongOperation1) doInBackground 在这个过程中我调用我的扫描仪并获取指纹图像,在后执行方法中,我必须将该指纹图像设置为另一个图像视图,问题是我无法在后执行中设置图像。(在我以前的代码中,我没有指定创建位图的扫描仪功能(bm)
  • 哦,我没看到。顺便说一句,我试图在 onPostExecute 中调用 setImageBitmap(bm) (尽管它是“null”),并且图像被正确设置为 NULL(它消失了)。尝试明确指定((AndroidHtmlActivity)上下文).runOnUiThread()的runOnUiThread。也许通过投射你可以解决它
  • 你的意思是在那个帖子里面执行
  • 是的,我做到了。通常,如果我没记错的话,runOnUiThread 必须在 onBackground 内部调用,因为在执行前和执行后,您仍在主 UI 中。顺便说一句...尝试一下不需要任何费用:)
【解决方案2】:

尝试在您的 CustomizeDialog 类中实现一个静态方法来更改您的图像,当您想要更改图片时,只需调用 CustomizeDialog.thatStaticMethod()。这样就是改变UI的原始类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-23
    • 2011-12-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多