我在我的应用中使用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);
}
}
答案 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);
}
}
方法。