【问题标题】:Dynamic android form from XML来自 XML 的动态 android 表单
【发布时间】:2014-09-29 12:40:16
【问题描述】:

我想在我的 activity_main.xml ScrollView 中生成一个表单。 XML 已正确加载和解析,但是当我尝试 addView(LinearLayout) 时,它会引发异常 e。我的应用程序通过推送通知获取 XML 文件的 url,然后对其进行解析。根据 XML,它应该生成一个表单并将其显示给用户。我以此为例:https://www.ibm.com/developerworks/xml/tutorials/x-andddyntut/#l1

这是我的主要活动:

public class MainActivity extends Activity {
// label to display gcm messages
TextView lblMessage;
Controller aController;
public ScrollView sv;
Button execute;

// Asyntask
AsyncTask<Void, Void, Void> mRegisterTask;

public static String name;
public static String email;

final Context context = this;

@Override
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ScrollView sv = (ScrollView) findViewById(R.id.sv);

...
}

// Create a broadcast receiver to get message and show on screen 
private final BroadcastReceiver mHandleMessageReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {

        String newMessage = intent.getExtras().getString(Config.EXTRA_MESSAGE);

        // Waking up mobile if it is sleeping
        aController.acquireWakeLock(getApplicationContext());

        ScrollView sv = (ScrollView) findViewById(R.id.sv);
        new DoInBackground(getApplicationContext(), sv).execute(newMessage);

        // Releasing wake lock
        aController.releaseWakeLock();

    }
};

这是我的异步类:

public class DoInBackground extends AsyncTask<String, Void, Void> {

Context mContext;
ScrollView mSv;

String tag = "DynamicFormXML";
XmlGuiForm theForm;
ProgressDialog progressDialog;
Handler progressHandler;

public DoInBackground(Context context, ScrollView sv) {

    this.mContext = context;
    this.mSv = sv;
}

@Override
protected void onPreExecute() {
    super.onPreExecute();

}

@Override
protected Void doInBackground(String... params) {

    if (GetFormData(params[0])) {
        DisplayForm();
    }
    else
    {
        Log.e(tag,"Couldn't parse the Form.");
        AlertDialog.Builder bd = new AlertDialog.Builder(mContext);
        AlertDialog ad = bd.create();
        ad.setTitle("Error");
        ad.setMessage("Could not parse the Form data");
        ad.show();

    }
    return null;
}


protected void onPostExecute() {

}

private boolean DisplayForm()
{

    try
    {           
        final LinearLayout ll = new LinearLayout(mContext);
        mSv.addView(ll); //Here it fails
        ll.setOrientation(android.widget.LinearLayout.VERTICAL);
...
    } catch (Exception e) { // Goes to here
        Log.e(tag,"Error Displaying Form");
        return false;
    }
}

我认为主要活动的上下文以及主要活动中的空 Scrollview 已正确转发(它们不为空),但我不是 100% 确定。任何帮助/提示表示赞赏! :)

【问题讨论】:

    标签: android xml android-layout android-asynctask android-custom-view


    【解决方案1】:

    您不能从后台线程(例如,运行 doInBackground 方法的线程)触摸 GUI。

    在AsynTask 中,您可以将UI 代码放在onPostExecute 中,它在UI 线程上调用,结果为doInBackground。

    如果您有中间结果,您可以从doInBackground 调用publishProgress,这将在 UI 线程上触发onProgressUpdate 的调用,您可以在其中更新 UI。

    请参阅AsyncTask API 获取示例以及有关必须在哪个线程上执行的更多详细信息。

    【讨论】:

      【解决方案2】:

      解决方案

      重新排序代码(因此 GUI 内容将在 PostExecute 上完成)有效。我也遇到了无法访问 onPostExecute() 的问题,但我不得不将其更改为 onPostExecute(Void result)。

      现在我的代码看起来像这样,就像一个魅力:

      public class DoInBackground extends AsyncTask<String, Void, Void> {
      
      Context mContext;
      LinearLayout mLl;
      
      String tag = "DynamicFormXML";
      XmlGuiForm theForm;
      ProgressDialog progressDialog;
      Handler progressHandler;
      
      public DoInBackground(Context context, LinearLayout ll) {
      
          this.mContext = context;
          this.mLl = ll;
      }
      
      @Override
      protected void onPreExecute() {
          super.onPreExecute();
      }
      
      @Override
      protected Void doInBackground(String... params) {
      
          getFormData(params[0]);
      
          return null;
      }
      
      protected void onPostExecute(Void result) {
          DisplayForm();
      }
      

      我还在我的 activity_main.xml 中添加了 ScrollView 和 LinearLayout,因此 DisplayForm() 看起来像这样(如果你想按照我之前提到的示例进行操作):

      private void DisplayForm() {
          try
          {           
      
              // walk thru our form elements and dynamically create them, leveraging our mini library of tools.
              int i;
              for (i=0;i<theForm.fields.size();i++) {
                  if (theForm.fields.elementAt(i).getType().equals("text")) {
                      theForm.fields.elementAt(i).obj = new XmlGuiEditBox(mContext,(theForm.fields.elementAt(i).isRequired() ? "*" : "") + theForm.fields.elementAt(i).getLabel(),"");
                      mLl.addView((View) theForm.fields.elementAt(i).obj);
                  }
          ...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-05
        • 1970-01-01
        • 1970-01-01
        • 2014-06-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多