【问题标题】:How to access controls(views)in tabs from another one in android?如何从android中的另一个标签访问控件(视图)?
【发布时间】:2015-06-19 04:54:47
【问题描述】:

我正在 eclipse 中开发有 5 个选项卡的应用程序,我为此花了很多时间,但现在我遇到了一个大问题:

当其中一个选项卡被激活时,下一个选项卡和上一个选项卡也正在加载 和onCreated() 方法被调用,但我不需要我只需要 切换标签时调用onCreated()方法

这是我的项目文件

ma​​inActivity.java

package info.androidhive.tabsswipe;
import info.androidhive.tabsswipe.adapter.TabsPagerAdapter;
import ir.zinoo.mankan.R;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.FragmentTransaction;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.content.SharedPreferences;


public class MainActivity extends FragmentActivity implements ActionBar.TabListener {


    private ViewPager viewPager;
    private TabsPagerAdapter mAdapter;
    private ActionBar actionBar;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Initilization

        viewPager = (ViewPager) findViewById(R.id.pager);
        actionBar = getActionBar();
        mAdapter = new TabsPagerAdapter(getSupportFragmentManager());



        viewPager.setAdapter(mAdapter);
        actionBar.setHomeButtonEnabled(false);
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

         //Adding Tabs
        for (String tab_name : tabs) {
            actionBar.addTab(actionBar.newTab().setTabListener(this));
        }
        actionBar.setStackedBackgroundDrawable(new ColorDrawable(Color.parseColor("#333333")));
        actionBar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#333333")));

        viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

            @Override
            public void onPageSelected(int position) {
                // on changing the page
                // make respected tab selected
                actionBar.setSelectedNavigationItem(position);
            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {

                }
            }

            @Override
            public void onPageScrollStateChanged(int arg0) {

            }
        });
    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {


    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        // on tab selected
        // show respected fragment view
        viewPager.setCurrentItem(tab.getPosition());

    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {

    }
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

tabPagerAdapter.java

package info.androidhive.tabsswipe.adapter;

import info.androidhive.tabsswipe.BmiFragment;
import info.androidhive.tabsswipe.CaloriFragment;
import info.androidhive.tabsswipe.FatFragment;
import info.androidhive.tabsswipe.KamarFragment;
import info.androidhive.tabsswipe.OstokhanFragment;
import info.androidhive.tabsswipe.OtherFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

public class TabsPagerAdapter extends FragmentPagerAdapter {

    public TabsPagerAdapter(FragmentManager fm) {
        super(fm);
    }
    @Override
    public Fragment getItem(int index) {

        switch (index) {
        case 0:
            // Top Rated fragment activity
            return new BmiFragment();
        case 1:
            // Games fragment activity
            return new CaloriFragment();
        case 2:
            // Movies fragment activity
            return new KamarFragment();
        case 3:
            // Movies fragment activity
            return new OstokhanFragment();
        case 4:
            // Movies fragment activity
            return new FatFragment();
        case 5:
            // Movies fragment activity
            return new OtherFragment();
        }

        return null;
    }

    @Override
    public int getCount() {
         //get item count - equal to number of tabs
        return 6;
    }

}

现在我的问题是如何避免在切换到特殊标签时调用其他标签的创建方法?

【问题讨论】:

    标签: android eclipse android-fragments android-tabs oncreate


    【解决方案1】:

    来自关于 FragmentPagerAdapter 的 Android 文档:

    此版本的分页器最适合在需要分页浏览一些通常更静态的片段(例如一组选项卡)时使用。用户访问的每个页面的片段将保存在内存中,尽管它的视图层次结构在不可见时可能会被破坏。这可能会导致使用大量内存,因为片段实例可以保持任意数量的状态。对于较大的页面集,请考虑 FragmentStatePagerAdapter

    FragmentStatePagerAdapter:

    这个版本的寻呼机在人多的时候比较有用 页面,更像是一个列表视图。当页面不可见时 用户,他们的整个片段可能会被销毁,只保留 该片段的保存状态。这允许寻呼机保持很多 与每个访问的页面相关的内存更少 FragmentPagerAdapter 以潜在的更多开销为代价 在页面之间切换。

    因此,当您使用FragmentPagerAdapter 时,FrgmentManager 将在用户使用应用程序时将所有片段添加到内存中。此外,当用户切换到任何页面时,FragmentManager 会加载previousnext 页面,它会调用您的标签页的onCreate()

    由于您现在有 6 个标签,可能要添加更多标签,FragmentStatePagerAdapter 更合适。

    要准确检查用户可以看到哪个片段,您可以执行以下操作:

    public class TabsPagerAdapter extends FragmentPagerAdapter {
    
    /* declare fragment objects here globally */
    BmiFragment mBmi = new BmiFragment();
    CaloriFragment mCalori = new CaloriFragment();
    KamarFragment mKamar = new KamarFragment();
    
    
    public TabsPagerAdapter(FragmentManager fm) {
        super(fm);
    }
    @Override
    public Fragment getItem(int index) {
    
        switch (index) {
        case 0:
            // Top Rated fragment activity
    
            mBmi.setUserVisibleHint(false);
            return mBmi;
        case 1:
            // Games fragment activity
    
            mCalori.setUserVisibleHint(false);
            return mCalori;
        case 2:
            // Movies fragment activity
    
            mKamar.setUserVisibleHint(false);
            return mKamar;
        /* like this for all case*/
        }
    
        return null;
    }
    
    }
    

    从您的 Activity 将 onPageChangeListener 设置为 ViewPager :

    mPager.setOnPageChangeListener(new OnPageChangeListener() {
                @Override
                public void onPageSelected(int position) {
                    // position tab is visible to user
                    switch(position) {
                        case 0 :
                            mBmi.setUserVisibleHint(true);
                            break;
                        /* like this for all case */
                     }
                }
            });
    

    在所有片段中重写 setUserVisibleHint() 方法:

    public class <Your_Fragment> extends Fragment {
      @Override
      public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser) {
            // do something, your fragment is visible
        } else {  
            // your fragment is loaded, but not visible to user currently
        }
      }
    }
    

    【讨论】:

    • 坦克我将 FragmentPagerAdapter 更改为 FragmentStatePagerAdapter 但仍在创建方法的下一个和上一个选项卡调用
    • 作为FragmentPagerAdapter 的实现,它将加载previousnext 片段...。我在回答中提到了这一点。如果onCreate() 被调用有什么问题吗?
    • 非常感谢您的关注是的,我需要在切换到选项卡时使用 onCreated() 或 OnShow() 或 onReload() 方法,而不是当我靠近它时,我想在它显示时做某事如果你知道还有什么可以做的,那可能会更好,因为语法不好,我不是英语
    • 您应该使用onResume() 并编写代码说明当用户可以看到某些片段时您想要做什么。让onCreate() 被框架调用,它不会损害您的应用程序和移动您的代码从 onCreate()onResume()
    • @Milaaaad :我已经编辑了我的答案。希望这会对你有所帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-10
    • 2011-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-01
    • 1970-01-01
    相关资源
    最近更新 更多