1

在我的应用程序中,我必须生成一个包含很多元素的大表单(一个元素通常是标签+属性(edditext、spinner、checkbox...))。

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

我试过的

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

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

问题

你知道有什么方法可以同时使用大量 UI 组件来保持良好的应用程序性能吗?您认为可以在用户开始滚动之前从 EditText 获取文本吗?

谢谢你。

4

1 回答 1

3

听起来你有某种偏好屏幕。如果是这种情况,请考虑使用PreferenceActivity。如果这行不通,那么 a 呢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));
}
于 2013-05-15T14:15:16.603 回答