2017-07-08 367 views
0

喜(我是新來這個,所以你得原諒我)從父活動訪問選項卡片段方法?

我現在有一個標籤式的活動,其中MainActivity.java是父類和Absences.javaNotices.java這些片段。我在MainActivity裏面有一個日期選擇器片段,當我點擊一個選項菜單按鈕時,它會運行。

當我成功選擇我的日期時,我想將信息傳遞給Absences片段中的方法。但是,我真的很難實現這個部分。

我已經做了研究似乎在暗示這是解決方案:

Absences fragment= (Absences) getSupportFragmentManager().findFragmentById(R.id.Absences); 
     ((Absences)fragment).updateAbsences(); 

然而,getSupportFragmentManager()不能從靜態上下文引用,我似乎無法找到我的片段的id 。

在做了一些更多的研究之後,似乎發現這種方法不適用於標籤式活動,所以我現在處於虧損狀態。

有人能夠指出我在正確的方向嗎? - 我已經在這個工作了很長一段時間了!

SectionsPageAdapter類

Fragment one, two; 

public class SectionsPagerAdapter extends FragmentPagerAdapter { 

    public SectionsPagerAdapter(FragmentManager fm) { 
     super(fm); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     // getItem is called to instantiate the fragment for the given page. 
     // Return a PlaceholderFragment (defined as a static inner class below). 
     switch (position) { 
      case 0: 
       if(one==null){ 
        one = new Absences(); 
       } 
       return one; 
      case 1: 
       if(two==null){ 
        two = new Notices(); 
       } 
       return two; 
     } 
     return null; 
    } 

    @Override 
    public int getCount() { 
     // Show 3 total pages. 
     return 2; 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     switch (position) { 
      case 0: 
       return "ABSENCES"; 
      case 1: 
       return "NOTICES"; 
     } 
     return null; 
    } 

} 

onOptionsItemSelected

public boolean onOptionsItemSelected(MenuItem item) { 
    int id = item.getItemId(); 
    if (id == R.id.calendar) { 
     DialogFragment newFragment = new DatePickerFragment(); 
     newFragment.show(getSupportFragmentManager(), "datePicker"); 
    } 
    return super.onOptionsItemSelected(item); 
} 

DatePickerFragment

public static class DatePickerFragment extends DialogFragment 
     implements DatePickerDialog.OnDateSetListener { 

    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 
     final Calendar c = Calendar.getInstance(); 
     int year = c.get(Calendar.YEAR); 
     int month = c.get(Calendar.MONTH); 
     int day = c.get(Calendar.DAY_OF_MONTH); 
     DatePickerDialog dialog = new DatePickerDialog(getActivity(), this, year, month, day); 
     dialog.getDatePicker().setMaxDate(c.getTimeInMillis()); 
     dialog.setTitle(""); 
     return dialog; 
    } 

    public void onDateSet(DatePicker view, int year, int month, int day) { 
     Absences fragment= (Absences) getSupportFragmentManager().findFragmentById(R.id.Absences); 
     ((Absences)fragment).updateAbsences(); 
    } 
} 

- 編輯 -

更新內部MainActivity

public void onDatePicked() { 
    Absences fragment = (Absences) getSupportFragmentManager().findFragmentById(R.id.absences); 
    fragment.updateAbsences(); 
} 

代碼按下面的建議

法新DatePickerFragment類

package com.alexwoohouse.heartofengland; 

import android.annotation.TargetApi; 
import android.app.DatePickerDialog; 
import android.app.Dialog; 
import android.icu.util.Calendar; 
import android.os.Build; 
import android.os.Bundle; 
import android.support.v4.app.DialogFragment; 
import android.util.Log; 
import android.widget.DatePicker; 

import java.util.Date; 

public class DatePickerFragment extends DialogFragment 
     implements DatePickerDialog.OnDateSetListener { 

    public interface OnDatePickedListener { 
     void onDatePicked(); //This method seems to be greyed out! 
    } 

    @TargetApi(Build.VERSION_CODES.N) 
    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 
     final Calendar c = Calendar.getInstance(); 
     int year = c.get(Calendar.YEAR); 
     int month = c.get(Calendar.MONTH); 
     int day = c.get(Calendar.DAY_OF_MONTH); 
     DatePickerDialog dialog = new DatePickerDialog(getActivity(), this, year, month, day); 
     dialog.getDatePicker().setMaxDate(c.getTimeInMillis()); 
     dialog.setTitle(""); 
     return dialog; 
    } 

    @TargetApi(Build.VERSION_CODES.N) 
    public void onDateSet(DatePicker view, int year, int month, int day) { 
     Calendar cal = Calendar.getInstance(); 
     cal.set(Calendar.YEAR, year); 
     cal.set(Calendar.MONTH, month); 
     cal.set(Calendar.DAY_OF_MONTH, day); 
    } 
} 
+0

你對「這是灰色」的評論 - 這是因爲你實際上並沒有使用界面。查看我鏈接到的文檔,它顯示瞭如何在附加到Activity時將接口的實例保存在片段中,然後在需要時調用它(在本例中,在您的'onDateSet'方法中) – dominicoder

回答

2

這裏是我的建議。

首先,將DatePickerFragment作爲自己的頂級班級。我不知道你是否有充分的理由讓它成爲一個靜態的內部階層,但你可能不需要這個。

現在,一般來說,你有片段(對話框或其他)傳遞信息的方式是通過接口回調。因此,您不必像現在那樣直接訪問當前活動的片段管理器,而是使用必須發送的數據調用回調。有關詳細信息和示例代碼見the android documentation on this,但基本上你定義在你的DatePickerFragment接口時的日期拾取會被調用:

public interface OnDatePickedListener { 
    void onDatePicked(Date date); 
} 

當你的片段連接到活動中,您保存爲片段的當前偵聽器實例。 當您在對話框片段中選擇日期時,您將調用偵聽器的onDatePicked方法。

你的活動,則實現此接口向下委託給要更新的片段:

public class MainActivity implements DatePickerFragment.OnDatePickedListner { 
    @Override 
    public void onDatePicked(Date date) { 
     Absences fragment = (Absences) getSupportFragmentManager().findFragmentById(R.id.Absences); 
     fragment.updateAbsences(); 
    } 
} 

主要利益的顧慮這是分離的。您的對話框片段不知道擁有它的任何活動。它只知道它必須將選擇的日期報告給實現接口的人。然後,只要他們也實現了正確的界面,就可以在任何其他需要選擇日期的活動中顯示此對話框片段。

希望有幫助!