繁体   English   中英

在Android中实现大型表单布局的最佳方法是什么?

[英]What is the best way to implement a large form layout in Android?

在我的应用程序中,我必须生成一个包含大量元素的大型表单(元素通常是带有label +属性(edditext,spinner,checkbox等)的)。

当表单包含更多元素(> 20)时,应用程序开始滞后,例如打开键盘大约需要1-2秒,或者滚动速度很慢。

我尝试了什么

  1. 此刻,每个元素都从xml(带有TextView和另一个组件的LinearLayout)中膨胀,并添加到表单布局中。 我试图“重用”(实际上是重新添加)一个元素,但是我得到一个例外,那就是该视图已经具有一个父级,这已经很有意义了,因为我已经被添加到表单布局中了。

  2. 我试图在ListView中添加所有元素,以确保重复使用视图。 它可以正常工作,但不是很好:在这种情况下,问题是如果我有一个EditText,则用户输入一些文本并滚动到列表的底部,我找不到从EditText保存文本的方法,所以我将当元素将再次在ListView中可见时(用户滚动回到我的元素),将其添加回EditText中。

您是否知道使用大量UI组件但同时又能保持良好应用性能的任何方式? 您是否认为可以在用户开始滚动之前从EditText获取文本?

谢谢。

听起来您有某种偏好屏幕。 如果是这种情况,请考虑使用PreferenceActivity 如果那行不通,那么ListView ,它具有内置的可重用布局的方法? 如果这些选项都不起作用,则可以创建自己的ViewAdapter ,其工作方式与ListView几乎相同。 只需创建一个类,例如MyViewAdapter 它应该包含参数以帮助配置其外观-例如标签文本和其他元素是什么:

public class MyViewAdapter {

    public static enum InputType {
        editor, spinner, checkbox
    };

    private CharSequence labelText;
    private InputType input;

    public MyViewAdapter(CharSequence text, InputType inputType) {
        this.labelText = text;
        this.input = inputType;
    }

}

至于要知道您的EditText什么文本,只需使用TextWatcher来监听对文本的更改。 尽管您可以在滚动回调之前和之后获得,但它需要破解内置的ScrollView 此示例被添加到以下代码中。

接下来,添加一个名为getView(Context)的方法,如下所示:

public View getView(Context context) {
    //here is where you inflate your view. For example:
    LinearLayout ll = new LinearLayout(context);
    ll.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
    ll.setOrientation(LinearLayout.VERTICAL);

    TextView tv = new TextView(context);
    tv.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
    tv.setText(labelText);
    ll.addView(tv);

    switch (input) {
        case (InputType.spinner) : {
            //TODO (see editor example)
            break;
        }
        case (InputType.checkbox) : {
            //TODO (see editor example)
            break;
        }
        default ://default to editor
        case (InputType.editor) : {
            EditText et = new EditText(context);
            et.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
            et.addTextChangedListener(new TextWatcher() {
                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                    // TODO Auto-generated method stub
                }

                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after){
                    // TODO Auto-generated method stub
                }

                @Override
                public void afterTextChanged(Editable s) {
                    // TODO Auto-generated method stub
                }
            });
            ll.addView(et);
            break;
        }
    }

    return ll;
}

最后,要使用此ViewAdapter,请在您的主要活动中创建它们:

List<MyViewAdapter> adapters = new ArrayList<MyViewAdapter>();//easy way to manage these.

//for each adapter, do something like:
adapters.add(new MyViewAdapter("myText:", InputType.editor));

然后,要放大视图,请执行以下操作:

//Let's say your Main View is a LinearLayout called myView.
for (MyViewAdapter adapter : adapters) {
    myView.addView(adapter.getView(context));
}

暂无
暂无

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

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