2013-04-10 52 views
2

我正在使用教程Manishkpr创建一个应用程序,您可以在1)layoutOne之间滑动:在此创建文件和2)layoutTwo:显示某个文件夹中所有创建文件的列表视图。从其他片段更新列表视图

问题:如果您创建了一个文件,它不会立即显示在列表视图中。我发现,我应该在LayoutOne.java使用此代码:

LayoutTwo fragment = (LayoutTwo) getFragmentManager().findFragmentByTag("TESTTWO"); 
      fragment.getAdapter().notifyDataSetChanged(); 

在LayoutTwo.java我说:

private static final String TAG = "TESTTWO"; 

//and the function getAdapter: 

public CustomArrayAdapter getAdapter() { 

     return adapter; 
    } 

不过,我对fragment.getAdapter().notifyDataSetChanged();得到一个空指针异常。我怎样才能解决这个问题,这是最好的方法吗?

编辑

myList = new ArrayList<RecordedFile>(); 

     File directory = Environment.getExternalStorageDirectory(); 
     file = new File(directory + "/test/"); 

     File list[] = file.listFiles(); 

     for (int i = 0; i < list.length; i++) { 
      if (checkExtension(list[i].getName()) == true) { 

       RecordedFile q = new RecordedFile(); 
       q.setTitle(list[i].getName()); 
       q.setFileSize(readableFileSize(list[i].length())); 


       myList.add(q); 
      } 
     } 

     adapter = new CustomArrayAdapter(myContext, 
       R.layout.listview_item_row, myList); 
     listView.setAdapter(adapter); 
+0

有人可以帮我吗?现在搜索几天,并得到它的头痛.. :) – 2013-04-12 13:50:37

回答

8

我使用Manishkpr教程,你刷1之间 创建一个应用程序)layoutOne:在这里,你创建一个文件和2)layoutTwo:显示了在特定的文件夹列表视图 所有创建的文件。

问题:如果您创建了一个文件,它不会立即显示在列表视图中 。

如果您只有两种布局可以滑动,则意味着两种布局都将在内存中显示并可供访问。然后,您可以分配一个ID,ListView,当它的时间来刷新数据简单地看为ListViewActivity,得到它的适配器和更新它,像这样:

ListView list = (ListView) getActivity().findViewById(R.id.theIdOfTheList); 
((BaseAdapter)list.getAdapter()).notifyDataSetChanged(); 

如果你打电话notifyDataSetChanged()不管在适配器上,ListView不会更新,因为它没有看到新文件,从它的角度来看,数据集是完整的。根据您的适配器的样子,你有两个选择:

重建ListView的数据,基本上重做你做了什么时,首先构建了ListView:检查目录和重新列表中的所有文件。

// create the new file 
File directory = Environment.getExternalStorageDirectory(); 
file = new File(directory + "/test/"); 
File list[] = file.listFiles(); 
ListView list = (ListView) getActivity().findViewById(R.id.theIdOfTheList); 
// I'm assuming your adapter extends ArrayAdapter(?!?) 
CustomArrayAdapter caa = (CustomArrayAdapter) list.getAdapter(); 
caa.clear(); 
for (int i = 0; i < list.length; i++) { 
    if (checkExtension(list[i].getName())) { 
     RecordedFile q = new RecordedFile(); 
     q.setTitle(list[i].getName()); 
     q.setFileSize(readableFileSize(list[i].length())); 
     caa.add(q); 
    } 
} 

或者你可以手动创建为新创建的文件RecordFile对象,并添加到现有的适配器:

ListView list = (ListView) getActivity().findViewById(R.id.theIdOfTheList); 
(CustomArrayAdapter) caa = (CustomArrayAdapter) list.getAdapter(); 
File newFile = new File("directory" + "/test/theNewFileName.extension"); 
RecordFile rf = new RecordFile(); 
rf.setTitle(newFile.getName()); 
rf.setFileSize(readableFileSize(newFile.length())); 
// have a method to return a reference of the data list(or a method 
// to add the data directly in the adapter) 
List<RecordFile> data = caa.getListData(); 
data.add(rf); 
caa.notifyDataSetChanged(); 

我不知道您的适配器的样子所以尽我说如果它不起作用,请发布适配器的代码。

+0

我没有得到我的代码中的任何错误,这是好的!但它不会更新ListView ...:s任何想法? – 2013-04-12 19:03:10

+0

@MatthiasVanb你可以更详细地解释一下ListView显示的内容吗?它如何从特定目录“查看”文件(如在应用程序的开始时如何查看当前文件)? – Luksprog 2013-04-12 19:10:07

+0

它基本上是我通过listFiles()函数获取的文件夹中的文件的列表视图。然后,我将信息放入RecordFile类的一个实例中,该实例在持有者的CustomAdapter中使用,以便在正确的位置显示它们。我用代码@Luksprog编辑我的问题 – 2013-04-12 23:03:08

1

我想这是因为viewpager加载layoutTwo,但你不与notifyDataSetChanged刷新。您只刷新LayoutTwo的数据,但不会刷新,因为viewpager有一个方法:pager.setOffscreenPageLimit(1); AFAIK这是默认值,所以接下来会发生在行中:加载LayoutOne,加载LayoutTwo,在layoutOne中执行任务,在布局中做两件事。但是,正如你所看到的那样,之后将没有负载布局。

我有一个非常类似的问题,它是一种解决方法,但重新开始活动(和pager.removeAllViews();),它运行良好,不会打扰用户。

但可以肯定,这将导致该问题,把这个在你的代码的按钮clicklistener:

viewPager.removeAllViews(); 
finish(); 
startActivity(new Intent(MyActivity.this, MyActivity.class)); 

这并不完全解决您的问题,但你会看到,如果在layoutTwo chaged或不是,得到问题的原因。

1

前段时间在项目中遇到了几乎相同的问题。

解决方案是将Observer模式添加到应用程序。

看一看有关该问题的官方文档:

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

会发生什么事是你与持有FragmentsActivity注册不同Fragments。无论何时Fragment正在更改,您将callback添加到您的Activity,而您的Activity将转而采取行动并将一些message交付给其他Fragments之一。

然后,您可以获得具体FragmentListView并更新它或您想要执行的任何操作。

这真的很简单,功能强大;-)

0

喜也许它有点晚了,但我努力做到这一点,这是我能够做到的方式。

这绝对不是最好的办法,但它的工作。

在开始时初始化您的片段,以便我们可以保存它们的每个实例,然后选择是否要实例化它们。

ExampleFragment searchFragment = null; 
ExampleFragment fileListFragment = null; 

现在改变FragmentStatePagerAdapter以下,所以我们用我们以前initialiazed片段

ExampleFragment searchFragment = null; 
ExampleFragment fileListFragment = null; 

现在的PagerAdapter类:

class pagerAdapter extends FragmentStatePagerAdapter 
{ 

    public pagerAdapter(FragmentManager fm) { 
     super(fm); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     // getItem is called to instantiate the fragment for the given page. 
     // Return a PlaceholderFragment (defined as a static inner class 
     // below). 
     switch (position) { 
     case 0: 
      if (searchFragment != null) { 
       return searchFragment; 
      } 
      return searchFragment = new ExampleFragment(); 
     case 1: 
      if (downFragment != null) { 
       return downFragment; 
      } 
      return downFragment = new ExampleFragment(); 
     } 
     return null; 
    } 

    @Override 
    public int getCount() { 
     return 2; 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     Locale l = Locale.getDefault(); 
     switch (position) { 
     case 0: 
      return getString(R.string.title_section1).toUpperCase(l); 
     case 1: 
      return getString(R.string.title_section2).toUpperCase(l); 
     } 
     return null; 
    } 

} 

这样,我们就可以调用里面的方法的每个片段,并从Main Activity与他们沟通,没有任何视图或上下文问题。

然后在onTabSelected方法的操作栏或任何其他"onChangeTab"类似的方法,你重置调用你想要从你的片段的方法。

@Override 
public void onTabSelected(ActionBar.Tab tab, 
     FragmentTransaction fragmentTransaction) { 
    // When the given tab is selected, switch to the corresponding page in 
    // the ViewPager. 
    if ((tab.getPosition()) == 1) { 
     downFragment.yourMethod(); 
    } 
    mViewPager.setCurrentItem(tab.getPosition()); 
} 

这不是优雅,但它是像一个魅力工作。