Препятствуйте тому, чтобы SWT ScrolledComposite ел часть, он - дети

Этот ответ может быть запоздалым, но я хотел бы упомянуть несколько вещей, когда ваш Activity зависит от AsyncTask. Это поможет вам предотвратить сбои и управление памятью. Как уже упоминалось в приведенных выше ответах, переходите к interface, мы также говорим, что они обратные вызовы. Они будут работать как информатор, но никогда не будут отправлять ссылки Activity или interface всегда использовать слабую ссылку в этих случаях.

Пожалуйста, обратитесь к скриншоту ниже, чтобы узнать, как это может вызвать проблемы.

Как вы можете видеть, начали ли мы AsyncTask с сильной ссылки, тогда нет гарантии, что наш Activity / Fragment будет до тех пор, пока мы не получим данные, поэтому было бы лучше использовать WeakReference в этих случаях, и это также поможет в управлении памятью, поскольку мы никогда не будем придерживаться сильной ссылки на наш Activity, тогда он будет иметь право на сбор мусора после его искажения.

Проверьте ниже фрагмент кода, чтобы узнать, как использовать awesome WeakReference -

MyTaskInformer.java Интерфейс, который будет работать как информатор.

public interface MyTaskInformer {

    void onTaskDone(String output);

}

MySmallAsyncTask.java AsyncTask выполняет длительную задачу, которая будет использовать WeakReference.

public class MySmallAsyncTask extends AsyncTask {

    // ***** Hold weak reference *****
    private WeakReference mCallBack;

    public MySmallAsyncTask(MyTaskInformer callback) {
        this.mCallBack = new WeakReference<>(callback);
    }

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

        // Here do whatever your task is like reading/writing file
        // or read data from your server or any other heavy task

        // Let us suppose here you get response, just return it
        final String output = "Any out, mine is just demo output";

        // Return it from here to post execute
        return output;
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);

        // Here you can't guarantee that Activity/Fragment is alive who started this AsyncTask

        // Make sure your caller is active

        final MyTaskInformer callBack = mCallBack.get();

        if(callBack != null) {
            callBack.onTaskDone(s);
        }
    }
}

MainActivity.java Этот класс используется для запуска моего AsyncTask реализации interface в этом классе и override этот обязательный метод.

public class MainActivity extends Activity implements MyTaskInformer {

    private TextView mMyTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mMyTextView = (TextView) findViewById(R.id.tv_text_view);

        // Start your AsyncTask and pass reference of MyTaskInformer in constructor
        new MySmallAsyncTask(this).execute();
    }

    @Override
    public void onTaskDone(String output) {

        // Here you will receive output only if your Activity is alive.
        // no need to add checks like if(!isFinishing())

        mMyTextView.setText(output);
    }
}

12
задан Lii 22 November 2017 в 12:03
поделиться

4 ответа

Это - общее препятствие при использовании ScrolledComposite. Когда это становится столь маленьким, что полосу прокрутки нужно показать, клиентское управление должно уменьшиться горизонтально для создания места для полосы прокрутки. Это имеет побочный эффект того, чтобы заставлять некоторые маркировки перенести строки, которые переместили следующие средства управления дальше вниз, которые увеличили минимальную высоту, необходимую довольному составной объект.

Необходимо прислушаться к изменениям ширины на довольном составной объект (mParent), вычислите минимальную высоту снова, учитывая новую ширину содержания и вызов setMinHeight() на прокрученном составном объекте с новой высотой.

public void createPartControl(Composite parent) {
  parent.setLayout(new FillLayout());
  ScrolledComposite scrollBox = new ScrolledComposite(parent, SWT.V_SCROLL);
  scrollBox.setExpandHorizontal(true);
  scrollBox.setExpandVertical(true);

  // Using 0 here ensures the horizontal scroll bar will never appear.  If
  // you want the horizontal bar to appear at some threshold (say 100
  // pixels) then send that value instead.
  scrollBox.setMinWidth(0);

  mParent = new Composite(scrollBox, SWT.NONE);

  FormLayout layout = new FormLayout();
  mParent.setLayout(layout);

  // Adds a bunch of controls here

  mParent.addListener(SWT.Resize, new Listener() {
    int width = -1;
    public void handleEvent(Event e) {
      int newWidth = mParent.getSize().x;
      if (newWidth != width) {
        scrollBox.setMinHeight(mParent.computeSize(newWidth, SWT.DEFAULT).y);
        width = newWidth;
      }
    }
  }

  // Wait until here to set content pane.  This way the resize listener will
  // fire when the scrolled composite first resizes mParent, which in turn
  // computes the minimum height and calls setMinHeight()
  scrollBox.setContent(mParent);
}

В прислушивании к изменениям размера обратите внимание, что мы игнорируем, любой изменяет размер событий, где ширина остается такой же. Это вызвано тем, что изменения в высоте содержания не влияют на минимальную высоту содержания, пока ширина является тем же.

12
ответ дан 2 December 2019 в 21:04
поделиться

Если я не ошибаюсь, необходимо подкачать

mParent.layout();

и

mParent.setSize(mParent.computeSize(SWT.DEFAULT, SWT.DEFAULT, true));

так, чтобы Вы имели:

public void createPartControl(Composite parent) {
  parent.setLayout(new FillLayout());
  ScrolledComposite scrollBox = new ScrolledComposite(parent, SWT.V_SCROLL);
  scrollBox.setExpandHorizontal(true);
  mParent = new Composite(scrollBox, SWT.NONE);
  scrollBox.setContent(mParent);
  FormLayout layout = new FormLayout();
  mParent.setLayout(layout);
  // Adds a bunch of controls here
  mParent.setSize(mParent.computeSize(SWT.DEFAULT, SWT.DEFAULT, true));
  mParent.layout();
}
2
ответ дан 2 December 2019 в 21:04
поделиться

Разве Вы не должны повторно вычислять размер ползунка после расположения?

0
ответ дан 2 December 2019 в 21:04
поделиться

Попытайтесь установить .setMinWidth и .setMinHeight на ScrolledComposite, после того как расположение было сделано, передав его размер основного составного объекта.

0
ответ дан 2 December 2019 в 21:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: