在其他片段

时间:2016-03-18 13:25:46

标签: android listview android-fragments tabs

我在我的应用中使用TabLayout作为选项卡式视图。我添加了三个List片段 - 每个标签一个。

当从任何片段添加/删除新记录时,应该更改任一片段的内容(并且必须更新列表视图)。

但在我修改一些数据并刷到下一个标签后,列表视图不会更新并保留旧数据。

我创建了一个在所有ListFragments中实现的接口,如下所示:

public interface UpdatableFragment {

    void updateContent();
}

public class LogFragment implements  UpdatableFragment{
...
    @Override
    public void updateContent() {

        Activity activity = getActivity();

        if (isAdded() && activity != null) {

            getLoaderManager().restartLoader(LOG_LIST_LOADER, null, this);
        }
    }
...
}

我在MainActivity选项卡中调用该方法选择监听器

 tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {

                if(adapter != null){

                    int position = viewPager.getCurrentItem();

                    viewPager = (ViewPager) findViewById(R.id.viewpager);
                    viewPager.setCurrentItem(position);

                    Fragment tabbedFragment =  adapter.getItem(viewPager.getCurrentItem());

                    if(tabbedFragment instanceof UpdatableFragment){

                        ((UpdatableFragment) tabbedFragment).updateContent();                               
                    }
                }
            }

但updateContent()方法中的条件if (isAdded() && activity != null)有时会返回false,因为activity变为null。在其他时候,它返回MainActivity实例并且加载器重新启动。

为什么会发生这种不一致的行为?如何在选择相应的标签时让ListFragments始终显示新内容?

EDIT 添加片段寻呼机代码

class ViewPagerAdapter extends FragmentPagerAdapter {

    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();

    public ViewPagerAdapter(FragmentManager manager) {
        super(manager);
    }

    @Override
    public Fragment getItem(int position) {

        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    public void addFragment(Fragment fragment, String title) {
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleList.get(position);
    }
}

1 个答案:

答案 0 :(得分:0)

getItem(int position)方法不会返回对Fragment当前位置ViewPager的引用。当getItem()调用PagerAdapter来创建您的观看次数/片段时instantiateItem()使用getItem(int position)方法,因此当您致电Fragment时,它会创建一个全新的Activity对你来说,这不会添加/附加到你的FragmentPagerAdapter.instantiateItem()(导致if检查中的false / null)。如果您查看getItem()的代码,可以看到它调用Fragment的位置,然后将FragmentManager添加到Fragment

解决此问题的一种方法是在FragmentPagerAdapter中缓存Fragment个引用(通过缓存instantiateItem()返回的adapter.destroyItem()来执行此操作,并删除adapter.notifyDataSetChanged()中的引用{1}}),或致电FragmentPagerAdapter以使用更新的数据重新创建您的观看次数。

<强>更新

您希望在public class Adapter extends FragmentPagerAdapter { private SparseArray<Fragment> fragmentCache = new SparseArray<>(); @Override public Object instantiateItem(ViewGroup container, int position) { Fragment fragment = (Fragment) super.instantiateItem(container, position); fragmentCache.put(position, fragment); return fragment; } @Override public void destroyItem(ViewGroup container, int position, Object object) { fragmentCache.remove(position); super.destroyItem(container, position, object); } // other code.... }

中添加类似内容
fragmentCache

然后,您可以从updateContent获取对适配器中当前所有片段的引用,然后您可以在其上调用 import javax.swing.JOptionPane; import javax.sound.sampled.*; import java.net.URL; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.ByteArrayInputStream; import java.util.Date; class AcceleratePlayback { public static void main(String[] args) throws Exception { double playBackSpeed = 1.5; File file1= new File("Sample3.wav"); File file2= new File("DEF.wav"); AudioInputStream ais = AudioSystem.getAudioInputStream(file1); AudioFormat af = ais.getFormat(); int frameSize = af.getFrameSize(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] b = new byte[65536]; int read = 1; while( read>-1 ) { read = ais.read(b); if (read>0) { baos.write(b, 0, read); } } byte[] b1 = baos.toByteArray(); byte[] b2 = new byte[(int)(b1.length/playBackSpeed)]; for (int i=0; i<(b2.length/frameSize); i++) { int ind=(int)((i*frameSize*playBackSpeed)); if((ind%2)==1) ind++; for (int j=0; j<frameSize; j++) { b2[(i*frameSize)+j] = b1[ind+j]; } } ByteArrayInputStream bais = new ByteArrayInputStream(b2); AudioInputStream aisAccelerated = new AudioInputStream(bais, af, b2.length/frameSize); AudioSystem.write(aisAccelerated, AudioFileFormat.Type.WAVE, file2); } } 方法。