Обнаружение изменений в модели данных Android - PullRequest
0 голосов
/ 12 сентября 2018

Я пытаюсь создать приложение с одним MainActivity и несколькими фрагментами.

В MainActivity я получаю данные и сохраняю их в модели данных. Например, получить время восхода, а затем отобразить его во фрагменте B. Как я могу обнаружить изменения значения восхода солнца и обновить TextView во фрагменте без перезапуска приложения? Есть ли способ прослушать измененное значение и обновить textView?

вот мои коды и макет фрагмента B.

Модель данных JAVA CLASS

public class SunriseTimeClass {
    private static final SunriseTimeClass INSTANCE = new SunriseTimeClass();
    public String sunrise = "";

    private SunriseTimeClass(){ }

    public static SunriseTimeClass getInstance(){
        return INSTANCE;
    }
}

MAINACTIVITY

    override fun onCreate(savedInstanceState: Bundle?) {

      //this will clear the back stack and displays no animation on the     screen
      var sunRise = SunriseTimeClass.getInstance()

      super.onCreate(savedInstanceState)
      setContentView(R.layout.activity_main)
      setSupportActionBar(toolbar)
      supportActionBar!!.setDisplayShowHomeEnabled(true)

      getSunriseSunset()
    }

    fun getSunriseSunset(){
      val location =  com.luckycatlabs.sunrisesunset.dto.Location("40.9167654", "-74.171811")
      val calculator =  SunriseSunsetCalculator(location, "America/New_York")
      sunRise.sunrise = calculator.getOfficialSunriseForDate(Calendar.getInstance())
    }

Компоновка ФРАГМЕНТА B

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text=""
        android:gravity="center"
        android:id="@+id/DisplaySunrise"/>
</FrameLayout>

Ответы [ 5 ]

0 голосов
/ 13 сентября 2018

Спасибо за все великолепные ответы.Я использовал SharePreference, чтобы сделать свою работу.работает как положено.

0 голосов
/ 13 сентября 2018
  1. Добавить фрагмент из действия



    FragmentManager fragmentManager = getSupportFragmentManager();
        android.support.v4.app.FragmentTransaction fragmentTransaction = 
     fragmentManager.beginTransaction();
     //frame_layout put in activity xml
     fragmentTransaction.add(R.id.frame_layout, drawer, "").commit();

  1. Получить экземпляр фрагмента и обновить ваши данные


    FragmentManager fragmentManager = getSupportFragmentManager();
    Fragment fragment = fragmentManager.findFragmentById(R.id.frame_layout);
    ((FragmentB)fragment).updateFragment("Updated value");

  1. Сделать публичный метод во фрагменте для обновления textview



    public void updateFragment(String value) {
            //update textview here
           Textview.setText(value);
     }

0 голосов
/ 12 сентября 2018

(код Java)

Создайте метод установки во фрагменте, который будет вызываться действием:

Во фрагменте:

public void setSunrise(String sunrise){
    this.sunrise = sunrise;
    //further operations..
}

А в действии:

Fragment fragment = new Fragment(); //your fragment
String s= calculator.getOfficialSunriseForDate(Calendar.getInstance());
fragment.setSunrise(s);
0 голосов
/ 12 сентября 2018

Если я вас правильно понял, вам нужно изменить / обновить фрагмент, когда что-то произойдет в Деятельности.

Так что я думаю, что вы могли бы реализовать интерфейс (обратный вызов) между Activity и Fragment.

1.Вы должны создать интерфейс в Activity:

   public interface OnActivityAction {
            void updateFragment();}

2.Вы должны объявить интерфейс и установщик в Activity и вызывать его, когда захотите

public OnActivityAction actionListener;

    public void setOnActionListener(OnActivityAction fragmentListener) {
        this.actionListener = fragmentListener;
    }

private void myActionToUpdate(){

      if (null != activityListener) {
            activityListener.doSomethingInFragment();
        }
}

3. Затем в вашем фрагменте необходимо реализовать этот интерфейс и настроить прослушиватель.

public class MyFragment extends Fragment implements OnActivityAction {

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);

         View rootView = inflater.inflate(R.layout.fragment_test_two, container, false);

        ((MainActivity) getActivity()).setOnActionListener(this);

         return rootView;
    }

    @Override
    public void updateFragment() {
        //Do whatever you want
    }
}

Надеюсь, это вам поможет.

0 голосов
/ 12 сентября 2018

Есть два возможных подхода к этому.

FragmentB получает данные sunRise и обновляет свой собственный TextView

Пусть FragmentB напрямую получит значения sunRise и обновит его TextView, вместо того, чтобы выполнять поиск в MainActivity.

OR

Связь между действием и фрагментом через интерфейс

Этот ответ аналогичен другому ответу в этой теме, но более подробно о том, как вы должны установить фрагмент TextView. Это решение делает несколько предположений и может быть упрощенным из-за ограниченной информации в вашем вопросе:

Предположение 1 : В этом решении предполагается, что метод getSunriseSunset является синхронным, т.е. не зависит от какой-либо услуги или сетевого вызова. Если он асинхронный, вам потребуется отдельный обратный вызов в вашем MainActivity (например, onSunriseRetrieved) для прослушивания, когда ваши данные возвращаются, до обновления вашего фрагмента.

Предположение 2 : Это решение также предполагает, что вы хотите получить доступ к представлениям фрагмента сразу после его добавления (следовательно, вызов executePendingTransactions). Тем не менее, если у вас FragmentB выполняет собственный поиск sunRise, то это предположение не понадобится.

Определите интерфейс в Деятельности и:

    public class MainActivity extends AppCompatActivity
    {    
        public interface OnSunriseChangeListener
        {
            void onSunriseChange(String newText);
        }

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

            if (savedInstanceState == null)
            {
                getFragmentManager()
                    .beginTransaction()
                    .add(R.id.fragment_container, new FragmentB()))
                    .commit();

                //assuming you want access to the fragment's views immediately
                getFragmentManager().executePendingTransactions();
            }

            getSunriseAndUpdateFragment(fragment);

        } 

        /**
         * Assumes that getSunriseSunset is synchronous and assumes that FragmentB is created. 
         */
        private void getSunriseAndUpdateFragment()
        {
            String newSunRiseValue = getSunriseSunset();
            ((FragmentB)getFragmentManager().findFragmentById(R.id.fragment_b)).onSunriseChange(newSunRiseValue);
        }

        // other code not shown...
    }

У FragmentB реализован интерфейс:

    public class FragmentB extends Fragment implements OnSunriseChangeListener
    { 

        @Override
        public void onSunriseChange(String newSunriseData)
        { 
            TextView textView = getView.findViewById(R.id.DisplaySunrise);
            textView.setText(newSunriseText);
        }
...