2013-05-15 5 views
0

В моем приложении мне нужно создать большую форму с множеством элементов (обычно это элемент и атрибут label + (edditext, spinner, checkbox, ...)).Каков наилучший способ реализовать макет большой формы в Android?

Когда форма содержит больше элементов (> 20), приложение начинает отставать, открывая клавиатуру, например, занимает 1-2 секунды или прокрутка выполняется медленно.

То, что я пытался

  1. В настоящее время каждый элемент надувается из XML (в LinearLayout с TextView и другого компонента) и добавляют для формирования макета. Я попытался «повторно использовать» (практически повторно добавить) элемент, но я получил и исключение, говоря, что у View уже есть родитель, который имеет смысл, поскольку я уже был добавлен в мой макет формы.

  2. Я попытался добавить все элементы в ListView, чтобы убедиться, что представления повторно используются. Он работает, но не правдоподобно: проблема в этом случае заключается в том, что если у меня есть EditText, пользователь вводит какой-то текст и прокручивает в нижней части списка, я не мог найти способ сохранить текст из EditText, чтобы я будет добавлен обратно в EditText, когда элемент снова будет виден в ListView (пользователь перейдет обратно к моему элементу).

Вопрос

Знаете ли вы, как использовать много компонентов пользовательского интерфейса, но в то же время, чтобы сохранить хорошую производительность приложения? Как вы думаете, можно ли получить текст из EditText непосредственно перед тем, как пользователь начнет прокрутку?

спасибо.

ответ

2

Похоже, у вас есть экран настроек. Если это так, подумайте об использовании 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)); 
} 
Смежные вопросы