从其父活动刷新一个片段列表的Android方法

21

我有一个主活动,其中包含带有3个菜单按钮的操作栏。

然后我在这个主活动中有一个片段,其中有一个列表。

当单击其中一个菜单按钮或者最好是仅删除列表中的所有行时,我想能够从主活动中刷新片段中的列表。

感谢任何帮助。

谢谢。

public class Favourite extends SherlockFragmentActivity {

    ActionBar actionBar;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.favourite);

        actionBar = getSupportActionBar();

        actionBar.setDisplayShowTitleEnabled(false);

        BitmapDrawable bg = (BitmapDrawable)getResources().getDrawable(R.drawable.actionbar_bg);
        bg.setTileModeX(TileMode.REPEAT); 
        getSupportActionBar().setBackgroundDrawable(bg);

        getSupportActionBar().setIcon(R.drawable.favourite_title);

        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        ActionBar.Tab tabAll = actionBar.newTab();
        ActionBar.Tab tabfavs = actionBar.newTab();
        ActionBar.Tab tabhist = actionBar.newTab();
        tabAll.setText("all");
        tabfavs.setText("favs");
        tabhist.setText("hist");
        tabAll.setTabListener(new MyTabListener());
        tabfavs.setTabListener(new MyTabListener());
        tabhist.setTabListener(new MyTabListener());
        actionBar.addTab(tabAll);
        actionBar.addTab(tabfavs);
        actionBar.addTab(tabhist);


        try{

        }
        catch(Exception e)
        {
        }
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        MenuInflater inflater = getSupportMenuInflater();
        inflater.inflate(R.menu.actionbar_itemlist_favourite, menu);

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch(item.getItemId()) {
                case R.id.history:
                    break;
                case R.id.favourite:
                    Intent favAct = new Intent(this, Favourite.class);
                    startActivity(favAct);
                    break;
                case R.id.delete:
                    ///I WANT TO BE ABLE TO REFRESH FRAGMENTLIST FROM HERE
                }
                return true;
    }

  }

class MyTabListener implements ActionBar.TabListener {

    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        if(tab.getPosition()==0)
        {
            FavouriteAllWords frag = new FavouriteAllWords();
            ft.replace(android.R.id.content, frag);

        }
        else if(tab.getPosition()==1)
        {
            FavouriteFavWords frag = new FavouriteFavWords();
            ft.replace(android.R.id.content, frag);

        }
        else if(tab.getPosition()==2)
        {
            FavouriteHistWords frag = new FavouriteHistWords();
            ft.replace(android.R.id.content, frag);
        }
    }

    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub

    }

    public void onTabReselected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub

    }

}

////////////////////我的列表片段类

public class FavouriteAllWords extends ListFragment {

    ArrayAdapter<String> adapter;

    List<String> stringOfFavWords;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup group, Bundle saved)
    {   
        adapter = new ArrayAdapter<String>(  
                inflater.getContext(), R.layout.row, stringOfFavWords);  
                setListAdapter(adapter);  

        return super.onCreateView(inflater, group, saved);  
    }

    @Override
    public void onActivityCreated (Bundle savedInstanceState)
    {   
        super.onActivityCreated(savedInstanceState);
    }

}

请问您能否展示一些代码,说明您已经完成了哪些工作?以及您在ActionBar中添加了哪个按钮? - Amit Prajapati
Biraj Zalavadia的回答是非常糟糕的设计方法。请看我的评论。 - Squonk
7个回答

35
你可以轻松地使用INTERFACE实现这一点。
MainActivity.java
public class MainActivity extends Activity {

    public FragmentRefreshListener getFragmentRefreshListener() {
        return fragmentRefreshListener;
    }

    public void setFragmentRefreshListener(FragmentRefreshListener fragmentRefreshListener) {
        this.fragmentRefreshListener = fragmentRefreshListener;
    }

    private FragmentRefreshListener fragmentRefreshListener;

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        Button b = (Button)findViewById(R.id.btnRefreshFragment);

        b.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(getFragmentRefreshListener()!=null){
                    getFragmentRefreshListener().onRefresh();
                }
            }
        });


    }


    public interface FragmentRefreshListener{
        void onRefresh();
    }

}

MyFragment.java

public class MyFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = null; // some view

        /// Your Code


        ((MainActivity)getActivity()).setFragmentRefreshListener(new MainActivity.FragmentRefreshListener() {
            @Override
            public void onRefresh() {

                // Refresh Your Fragment
            }
        });


        return v;
    }
}

2
这完全是错误的做法。Fragment 永远不应该 知道它所附加的 Activity 的类型。特别地,如果一个 Fragment 要是自包含和可重用的,怎么能保证 Activity 已经定义了任何特定的接口呢?简短的回答是 - 不能。 - Squonk
6
不要惊慌,朋友。仔细阅读问题。他清楚地写明我想从MainActivity.java刷新片段。他没有说他的片段是通用的。因此,我发布的答案与问题有关,而不是一般用途。如果您有更好的方法,请发帖而不是争论。 - Biraj Zalavadia
1
@BirajZalavadia:来自“localhost”的答案中的第一点是正确的。一个Activity将始终“知道”它使用的所有Fragments,但Fragments不应该“知道”它们所附加到的任何Activity的任何信息,除了检查Activity是否实现了Fragment自己的接口(必要时)。简而言之,一个Fragment可以定义任意数量的公共方法,如果需要,Activity可以直接调用它们。这种方法在此链接中有所涵盖...http://developer.android.com/training/basics/fragments/communicating.html#Deliver - Squonk
无法将片段实例保存在属性中并从中调用公共方法吗? - JCarlosR
@JCarlos 是的,那也是可能的。 - Biraj Zalavadia
显示剩余4条评论

5
你的活动可以通过获取Fragment的引用来调用该Fragment中的方法。
(1)在添加Fragment时提供一个标签。
transaction.add(R.id.fragment_container, myFragment, "myfragmentTag");

(2) 在你的主机托管活动中,你可以找到该片段并访问它的方法。

FragmentManager fm = getSupportFragmentManager();
myFragment f = (myFragment) fm.findFragmentByTag("myfragmentTag");
f.refreshAdapter()

(3) refreshAdapter() 现在可以调用 adapter.notifyDataSetChanged()。

这是向片段通信的推荐方式之一。 接口实现主要用于向活动返回信息。


5
  • 只需将您的更新/刷新方法设为公共方法,并从Activity中调用它。

或者

  • 使用LocalBroadcastManager或EventBus从Activity发送事件,通过在Fragment中订阅此事件来对其进行响应并调用刷新/更新方法。

1
“Fragment”不需要成为“Activity”的内部类才能使用公共方法。只要“Activity”具有对“Fragment”实例的引用,它就可以调用“Fragment”中的任何公共方法。 - Squonk

1
Biraj Zalavadia的答案是100%正确的,您将从使用接口调用任何片段方法... 这个接口方法在没有错误的情况下运行...
在MainActivity中,在oncreate之前使用以下内容 private FragmentRefreshListener fragmentRefreshListener;
public FragmentRefreshListener getFragmentRefreshListener() {
    return fragmentRefreshListener;
}

public void setFragmentRefreshListener(
        FragmentRefreshListener fragmentRefreshListener) {
    this.fragmentRefreshListener = fragmentRefreshListener;
}

在Activity内部
private void refreshcall(String result2) {
    // TODO Auto-generated method stub
    if (getFragmentRefreshListener() != null) {
        getFragmentRefreshListener().onRefresh(result2);
    }

}

并将其放入所需的片段中。
private FragmentRefreshListener fragmentRefreshListener;

    public FragmentRefreshListener getFragmentRefreshListener() {
        return fragmentRefreshListener;
    }

    public void setFragmentRefreshListener(
            FragmentRefreshListener fragmentRefreshListener) {
        this.fragmentRefreshListener = fragmentRefreshListener;
    }

0

0

当您单击ActionBar上的任何按钮时,请调用接口以刷新ListFragment。因为在Java中,接口用于互通。


-1
在 Kotlin 中,从活动中获取支持片段列表,检查实例,然后调用片段函数。
val fragments = supportFragmentManager.fragments
            for (fragment in fragments) {
                if (fragment is HomeCategoriesFragment) {
                    fragment.updateAdapter() // Define function in Fragment 
                }
            }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接