7

我尝试开发第一个从网络下载图像并在网格视图中显示它们的应用程序。gridview 是主 Activity 的一个片段。下载过程是使用 onCreate 函数中的 AsyncTask 完成的。为了在更改方向时不会再次下载图像,我android:configChanges="orientation|screenSize"在 Android Manifest 中设置了 。然后 onCreate 函数只调用一次,一切都很好......除了我必须在横向模式下对 gridview 片段的布局进行一些更改。所以我创建了 2 个布局表:fragment_library.xmlfragment_library_land.xml在布局/文件夹中。为了使这些更改生效,我尝试使用 onConfigurationChanged 函数手动更改库片段的布局。在运行时,程序评估函数并传入好的情况(纵向或横向),但使用的布局仍然是纵向模式的布局:fragment_library.xml...

public class LibraryFragment extends Fragment {
    public GridView gridview;
    private Boolean isImageAdapterPopulated = false;

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        GetLibraryTask getLibraryTask = new GetLibraryTask(this);
        getLibraryTask.execute(Config.URL + "action=getLibrary");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        if (container == null)
            return null;

        // gridview
        View V = inflater.inflate(R.layout.fragment_library, container, false);
        gridview = (GridView)V.findViewById(R.id.gridview);

        if(this.isImageAdapterPopulated)
            this.setGridAdapter();
        return V;
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig){
        super.onConfigurationChanged(newConfig);
        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
            LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService( Context.LAYOUT_INFLATER_SERVICE );
            inflater.inflate(R.layout.fragment_library_land, null);
        } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
            LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService( Context.LAYOUT_INFLATER_SERVICE );
            inflater.inflate(R.layout.fragment_library, null);
        }
    }

    public void setGridAdapter(){
        this.isImageAdapterPopulated = true;
        gridview.setAdapter(new ImageAdapter(getActivity()));
    }

    // ...
}

片段库.xml

<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/gridview"
    android:cacheColorHint="@android:color/transparent"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"
    android:columnWidth="200dp"
    android:numColumns="auto_fit"
    android:verticalSpacing="10dp"
    android:horizontalSpacing="20dp"
    android:stretchMode="columnWidth"
    android:gravity="bottom"
/>

fragment_library_land.xml

<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/gridview"
    android:cacheColorHint="@android:color/transparent"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"
    android:columnWidth="400dp"
    android:numColumns="2"
    android:verticalSpacing="50dp"
    android:horizontalSpacing="50dp"
    android:stretchMode="columnWidth"
    android:gravity="bottom"
/>

感谢帮助 :)

4

2 回答 2

16

这不可能。Fragment 无法动态更新其布局。但是,您确实有其他一些选择。

1 . 不喜欢这个,但你可能有一个 Fragment 的布局,同时具有纵向和横向视图,并显示和隐藏。

片段库.xml:

<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/gridview_portrait"
    android:cacheColorHint="@android:color/transparent"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"
    android:columnWidth="200dp"
    android:numColumns="auto_fit"
    android:verticalSpacing="10dp"
    android:horizontalSpacing="20dp"
    android:stretchMode="columnWidth"
    android:gravity="bottom"
/>
<GridView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/gridview_landscape"
    android:cacheColorHint="@android:color/transparent"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"
    android:columnWidth="400dp"
    android:numColumns="2"
    android:verticalSpacing="50dp"
    android:horizontalSpacing="50dp"
    android:stretchMode="columnWidth"
    android:gravity="bottom"
    android:visible="gone"
/>

然后是一些私有成员变量:

private GridView mGridViewPortrait;
private GridView mGridViewLandscape;

然后在onConfigurationChanged(Configuration newConfig)

@Override
        public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);

            if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
                 mGridViewPortrait.setVisibility(View.VISIBLE);
                 mGridViewLandscape.setVisibility(View.GONE);
            }

            else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
                 mGridViewPortrait.setVisibility(View.GONE);
                 mGridViewLandscape.setVisibility(View.VISIBLE);
            }
        }

几点:请注意,我省略了引用两个 GridView 的代码。我还将您的 GridView 更改为私有,并将名称更改为 mGridView*。私有以保持“数据封装”和“m”,因为它是该类的成员,只是约定。我还更改了 if-else 子句,因为我希望先进行纵向检查。

这种方式是最快和最简单的,但是如果你有很大的布局它可能会变得很重,所以如果你有很多东西就不要使用它。最好不要使用这种方法。

2 . 正确的方法是让 Andorid 处理方向并将您的 XML 移动到正确的目录。但是,这将重新创建您的 Fragment (如果您没有设置setRetainInstance(true);,在这种情况下您不会设置;这将使 Fragment 不会重新创建它的布局(实际上查找它未提及的保留方法onCreateView,因此您也可以尝试将其设置为 true并尝试))。

将您的 fragment_library_land.xml 移动到目录 layout-land 而不是 layout 并将其命名为fragment_library .xml。注意粗体,它将具有相同的名称但位于不同的目录中。这样,Android 将根据方向了解并采用正确的布局。

如果我理解了为什么你不想重新创建 Fragment 因为onCreate(Bundle savedInstanceState)会再次被调用(setRetainInstance(true);它不会并且关于我之前写的你可以试一试)从而创建一个新实例GetLibraryTask并再次下载图像. 如果您使用数据库来存储图像,并且如果您有一个布尔值来跟踪您是否下载了图像,则可以防止这种情况发生。然后,GetLibraryTask您将挑选出未下载的图像,无论是第一次运行任务还是方向改变。您还需要在下载循环中的库任务中进行停止检查,在每个项目之前检查您是否应该下载图像或片段是否不再可用并因此退出任务。

现在,当您更改方向时,Activity 将重新创建 LibraryFragment,并根据方向使用 layout 或 layout-land。

代码中的一些旁注:

  • 正如我之前写的,永远不要使用公共访问,必要时总是使用私有或受保护。Private 可以一直使用,并且有 getter 和 setter(访问器和 mutator)来进行通信。
  • 使用“m”作为成员变量的前缀,在这种情况下public GridView gridview将是private GridView mGridView并且private Boolean isImageAdapterPopulated将会是private boolean mIsImageAdapterPopulated
  • 如果不需要,切勿将类用于原始类型。您可能在不支持原始类型或类保留等的列表中需要它。
  • onConfigurationChanged(Configuration newConfig)你膨胀一个 XML 并返回一个视图,但你没有用它做任何事情

祝你好运!

于 2013-01-29T09:58:06.663 回答
0

It is possible if you will use oncongi change method. please see this link Change Fragment layout on orientation change

于 2014-03-14T10:36:35.473 回答