Max*_*ess 7 layout android runtime fragment orientation
我尝试开发第一个从网上下载图像并在gridview中显示它们的应用程序.gridview是主Activity的片段.下载过程是使用onCreate函数中的AsyncTask完成的.为了在更改方向时不再下载图像,我android:configChanges="orientation|screenSize"在Android Manifest中设置了它.然后onCreate函数只调用一次,一切都很好......除了我必须在横向模式下对gridview片段的布局进行一些更改.所以我创建了2个布局表:fragment_library.xml并fragment_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()));
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
fragment_library.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"
/>
Run Code Online (Sandbox Code Playgroud)
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"
/>
Run Code Online (Sandbox Code Playgroud)
感谢帮助 :)
Sim*_*all 16
这不可能.片段无法动态更新其布局.但是你确实有其他一些选择.
1.不是这个的粉丝,但你可能同时拥有Fragment的布局同时包含肖像和水平视图并显示和隐藏.
fragment_library.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"
/>
Run Code Online (Sandbox Code Playgroud)
然后是一些私有成员变量:
private GridView mGridViewPortrait;
private GridView mGridViewLandscape;
Run Code Online (Sandbox Code Playgroud)
然后在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);
}
}
Run Code Online (Sandbox Code Playgroud)
一些要点:请注意,我省略了代码以引用两个GridView.我还将GridView更改为private,并将名称更改为mGridView*.私有以保持"数据封装"和"m",因为它是类的成员,只是约定.我也改变了if-else子句,因为我想先将肖像检查放在首位.
这种方式是最快速和最简单的,但是如果你有大的布局,它可能会变得很重,所以如果你有很多东西就不要使用它.最好不要使用这种方法.
2.正确的方法是让Andorid处理方向,并将XML移动到正确的目录.然而,这将重新创建你的片段(如果你没有设置setRetainInstance(true);你不会在这种情况下;这将使片段不重新创建它的布局(实际上查找它没有提到的保留方法,onCreateView所以你可以尝试将其设置为真如此并尝试)).
将fragment_library_land.xml移动到目录layout-land而不是layout,并将其命名为fragment_library .xml.注意粗体,它将具有相同的名称,但保留在不同的目录中.这样Android就会根据方向知道并采取正确的布局.
如果我已经理解为什么你不想重新创建片段,因为onCreate(Bundle savedInstanceState)它将被再次调用(setRetainInstance(true);它不会和我之前写的那样你可以尝试一下)从而创建一个新实例GetLibraryTask并再次下载图像.如果您使用数据库存储图像,并且如果您有一个布尔值,如果您已下载图像,则可以防止这种情况.在GetLibraryTask你那么会挑出未下载的图像,无论是第一次运行任务,或者如果方向改变.您还需要在下载循环中的库任务中进行停止检查,在每个项目检查之前是否应该下载图像,或者片段是否不再可用,从而退出任务.
现在,当您更改方向时,Activity将重新创建LibraryFragment,并根据方向使用layout或layout-land.
您的代码中的一些附注:
public GridView gridview将是private GridView mGridView和private Boolean isImageAdapterPopulated将来的private boolean mIsImageAdapterPopulatedonConfigurationChanged(Configuration newConfig)你膨胀XML并返回一个View但你没有做任何事情祝你好运!