从另一个片段调用一个片段中的方法

Posted

技术标签:

【中文标题】从另一个片段调用一个片段中的方法【英文标题】:Calling a method in one fragment from another 【发布时间】:2015-01-28 19:22:34 【问题描述】:

当在其他片段中按下按钮时,我已经尝试了一段时间(以及在此处搜索)以帮助我刷新 MainFragment 中的 listView。有人能解释一下如何使它工作吗?

这是带有函数的 MainFragment(我排除了其他函数,因为我看不到它们的贡献):

public class MainFragment extends Fragment 
public void otherList() 
    SQLite db = new SQLite(getActivity());
    db.open();
    Calendar sCalendar = Calendar.getInstance();
    String day = sCalendar.getDisplayName(Calendar.DAY_OF_WEEK,
            Calendar.LONG, Locale.ENGLISH);
    Cursor c = db.getAllRecords(day);
    Calendar cal = Calendar.getInstance();
    int hour = cal.get(Calendar.HOUR_OF_DAY);
    arrayOfBars.clear();
    if (c.moveToFirst()) 
        do 
            String country = c.getString(0);
            String city = c.getString(1);
            String bar = c.getString(2);
            String timeStart = c.getString(3);

            String[] h = timeStart.split(":");
            int times = Integer.parseInt(h[0]);

            String timeEnd = c.getString(4);
            String[] h2 = timeEnd.split(":");
            int timee = Integer.parseInt(h2[0]);

            String placeLaLo = c.getString(5);
            String description = c.getString(6);
            String likes = c.getString(7);
            String offer = c.getString(8);

            if (hour < (times + 1) || hour < (timee)) 
                getPrefs = PreferenceManager
                        .getDefaultSharedPreferences(MainFragment.this
                                .getActivity());
                boolean lay = getPrefs.getBoolean("boolean", false);
                if (lay == true) 
                    while (times < timee) 
                        timeStart = times + ":" + h[1];
                        times++;
                        timeEnd = times + ":" + h2[1];
                        arrayOfBars.add(new BarObject(country, city, bar,
                                timeStart, timeEnd, placeLaLo, description,
                                likes, offer, bar));
                    
                 else 
                    arrayOfBars.add(new BarObject(country, city, bar,
                            timeStart, timeEnd, placeLaLo, description,
                            likes, offer, bar));
                
            

         while (c.moveToNext());

        Collections.sort(arrayOfBars, new BarObject.CompST());

        lv2.setAdapter(null);
        adapter = new BarAdapter(getActivity(), arrayOfBars);
        lv2.setAdapter(adapter);
     else 
        Toast.makeText(getActivity(), "No database found",
                Toast.LENGTH_LONG).show();
    
    db.close();

这是另一个片段:

public class SocialMedia extends Fragment 
ImageButton facebook, twitter, layoutS;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 
    View view = inflater.inflate(R.layout.social_media, container, false);
    layoutS = (ImageButton) view.findViewById(R.id.ibLayout);

    layoutS.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            SharedPreferences getPrefs = PreferenceManager
                    .getDefaultSharedPreferences(SocialMedia.this
                            .getActivity());
            boolean lay = getPrefs.getBoolean("boolean", false);
            SharedPreferences.Editor e = getPrefs.edit();
            lay = !lay;
            e.putBoolean("boolean", lay);
            e.commit();
                            //Here I want to call otherList() from MainFragment
        
    );
    return view;

【问题讨论】:

FragmentManager fm = getFragmentManager(); MainFragment fragem = (MainFragment)fm.findFragmentById(R.id.main_fragment); fragem.otherList();,为我工作 【参考方案1】:
FragmentManager fm = getFragmentManager(); 
MainFragment fragm = (MainFragment)fm.findFragmentById(R.id.main_fragment); 
fragm.otherList(); 

这段代码最适合我。而且看起来很简单

【讨论】:

什么是 R.id.main_fragment?片段布局或加载哪个片段的布局?“我在 viewpager 中有片段” @JamaldinSabirjanov 你明白了吗?当我使用此代码时,我的应用程序崩溃了... @JMB 不,我将变量设为“公共静态”并从另一个片段中使用它们。 main_fragment 未定义 findFragmentById(R.id.main_fragment)???这是一个不完整的答案。 ...一个问题...没有人知道如何设置片段 ID ...根本没有可靠的文档【参考方案2】:

在 MainFragment 类中您可以执行以下代码:

private static MainFragment instance = null;

@Override  
public void onCreate(@Nullable Bundle savedInstanceState)   
    super.onCreate(savedInstanceState);  
    instance = this;  


public static MainFragment getInstance()   
    return instance;  
 

在 SocialMedia 类中,您可以按如下方式调用该方法:

MainFragment.getInstance().otherList();   

【讨论】:

它显示了这个警告:不要将android上下文类放在静态字段中;这是内存泄漏(也会破坏 Instant Run)【参考方案3】:

您应该为此使用interface。在OtherFragment 类中定义interface 并在MainActivity 中实现它,并在MainFragment 中定义public 方法以刷新ListView 并从MainActivity 调用该方法。这是一个例子:

public Class OtherFragment extends Fragment implements OnClickListener 

private Communicator communicator;

   ...

public void setCommunicator(Communicator communicator) 
    this.communicator = communicator;


@Override
public void onClick(View v) 
   communicator.clicked();


   public interface Communicator 
      public void clicked();
   

在你的MainActivity

public class MainActivity extends Activity implements OtherFragment.Communicator 

   MainFragment mainFragment;

   @Override
   protected void onCreate(Bundle b) 
      ...
      OtherFragment otherFragment = new OtherFragment();
      otherFragment.setCommunicator(this);
      ...
   

   ...

   @Override 
   public void clicked() 
     mainFragment.updateList();
   

在您的MainFragment 中:

public class MainFragment extends Fragment 

    ...

    public void updateList() 
        // update list
    

【讨论】:

老实说我不会尝试实现它,因为我同时找到了一个简单的解决方案。感谢您的贡献时间 @KManos 简单的解决方案是什么?【参考方案4】:

要从另一个对象(片段是一个对象)调用方法,您需要拥有该对象的引用。因此,如果您想从SocialMedia 实例调用MainFragment#otherList()SocialMedia 需要引用MainFragment

例如:

public class SocialMedia 

    private MainFragment mainFragment = null;

    public void setMainFragment(final MainFragment mainFragment) 
        this.mainFragment = mainFragment
    

那么你可以使用this.mainFragment.otherList()

【讨论】:

我认为将Fragment 传递给另一个Fragment 不是一个好的解决方案 没有用 - 它只是让我的应用程序崩溃。但与此同时,我确实找到了一个简单的解决方案。 @KManos 它可能崩溃了,因为您没有设置片段并且它为空。 @KManos 那么你应该发布你的解决方案,这样我们都可以学习:) 我认为它反对封装,如果你使用这种方法,你的片段不再是模块化的,你不能在应用程序的其他地方使用它们。【参考方案5】:
            // Calling Parent Fragment method from Child Fragment.
        // Child Fragment
        AppCompatActivity activity = (AppCompatActivity) view.getContext();
        FragmentManager fragmentManager = activity.getSupportFragmentManager();
        NavigateFragment navigateFragment = (NavigateFragment) fragmentManager.findFragmentById(R.id.fragment_place_dashboard);
        navigateFragment.sayHelloWorld();


        // -- Some method in Parent Fragment(NavigateFragment).
        public void sayHelloWorld()
            Log.d(TAG, "Hello World.");
        

【讨论】:

以上是关于从另一个片段调用一个片段中的方法的主要内容,如果未能解决你的问题,请参考以下文章

如何从另一个活动中调用片段

如何在将 Tablayout 与 viewpager 一起使用时从另一个片段调用 AsyncTask?

从适配器中的片段调用元素

片段中的空指针异常

从另一个提供循环依赖的模块打开活动

安卓。通过从片段中的按钮调用片段中的方法来关闭片段?