【问题标题】:Android refresh a fragment list from its parent activityAndroid从其父活动刷新片段列表
【发布时间】:2014-10-28 10:56:44
【问题描述】:

我有一个主要活动,其中包含带有 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);
    }

}

【问题讨论】:

  • 请你显示一些代码,你做了什么?以及您在操作栏中添加了哪个按钮
  • Biraj Zalavadia 的回答是一种非常糟糕的设计方法。请参阅我对他的回答的评论。

标签: android android-fragments android-listfragment


【解决方案1】:

您可以使用 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;
    }
}

【讨论】:

  • 这完全是错误的做事方式。 Fragment 应该永远“知道”它所附加的Activity 的类型。特别是,如果 Fragment 是独立的和可重用的,如何保证 Activity 定义了任何特定的接口?简短的回答 - 它不能。
  • @Squonk 朋友不要惊慌。仔细阅读问题。他清楚地写道,我想从 MainActivity.java 刷新片段。他没有说他的片段是一般的。所以我发布的答案与问题有关,而不是出于一般目的。如果您有更好的方法,请发帖争论。
  • @BirajZalavadia :来自“localhost”的答案中的第一点是正确的。 Activity 将始终“了解”它使用的 Fragments 的所有信息,但 Fragments 永远不应“了解”它们所附加的任何 Activity 的任何信息,除非检查 Activity 是否实现了 Fragment's 自己接口(必要时)。简而言之,Fragment 可以定义任意数量的公共方法,Activity 可以在需要时直接调用它们。此链接中介绍了这种方法...developer.android.com/training/basics/fragments/…
  • 这也是实现这一目标的一种方法。但是你不能说接口是非常糟糕的方法。即使是这种方法,Fragmnet 也可能不为空,但它没有附加到窗口。在这种情况下,应用程序将崩溃。所以我的意思是,可以有几种方法各有利弊。所以我们不能说这是完美的。
  • @BirajZalavadia:你仍然没有理解我的意思。在您的代码中,您使用((MainActivity)getActivity()).setFragmentRefreshListener(new MainActivity.FragmentRefreshListener() {...) - 您明确使用MainActivityFragment 的意义在于它应该是可重用的——如果有人想使用附加到AnotherActivityAnyOtherActivityMyFragment 实例会发生什么?每次使用 Fragment 代码来转换正确的 Activity 类时,您都必须对其进行编辑。它所需要的只是Fragment 中的一个公共方法,EVERY Activity 可以按原样使用它。想一想
【解决方案2】:
  • 只需公开您的更新/刷新方法并从您的活动中调用它。

  • 使用 LocalBroadcastManager 或 EventBus 从您的 Activity 发送事件,并通过在 Fragment 中订阅此事件 - 对其做出反应并调用刷新/更新方法。

【讨论】:

  • Fragment 不需要是Activity 的内部类才能使用公共方法。只要Activity有对Fragment实例的引用,就可以调用Fragment中的任何公共方法。
【解决方案3】:

您的 Activity 可以通过获取对 Fragment 的引用来调用 Fragment 中的方法。

(1) 添加片段时提供标签。

transaction.add(R.id.fragment_container, myFragment, "myfragmentTag");

(2) 在您的 hosting 活动中,您可以找到片段并可以访问它的方法。

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

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

这是与片段通信的推荐方式之一。 接口实现主要是为了和activity进行通信。

【讨论】:

    【解决方案4】:

    Biraj Zalavadia 的回答是 100% 正确,您将使用接口调用不片段方法.... 这个接口方法运行没有错误...

    在 oncreate 上面的 MainActivity 中使用它 私有 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;
        }
    

    【讨论】:

      【解决方案5】:

      与其他片段通信

      http://developer.android.com/training/basics/fragments/communicating.html

      这也可以用于 Activity 和 Fragment 之间的通信。

      【讨论】:

        【解决方案6】:

        当你点击ActionBar任意一个Button然后调用接口刷新ListFragment。因为在java中接口是用于相互通信的。

        【讨论】:

          【解决方案7】:

          在 Kotlin 中 从activity中获取Support Fragment列表,勾选Instance,然后调用fragment函数

          val fragments = supportFragmentManager.fragments
                      for (fragment in fragments) {
                          if (fragment is HomeCategoriesFragment) {
                              fragment.updateAdapter() // Define function in Fragment 
                          }
                      }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-06-09
            • 1970-01-01
            • 2017-08-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-11-03
            相关资源
            最近更新 更多