Fragment详解(三)--->横竖屏幕切换完整示例

MainActivity如下:

package cc.testsimplefragment2;

import android.app.Activity;
import android.os.Bundle;
/**
 * Demo描述:
 * Fragment使用示例
 *
 * 备注说明:
 * 1 在main.xml中存在一个Fragment即
 *   TitleListFragment.用它来显示Titles
 * 2 点击TitleListFragment中的某个条目的时候
 *   判断的横竖屏
 *   2.1 若是横屏,则用另外一个Fragment显示详细信息
 *   2.2 若是竖屏,则启动另一个Activity显示详细信息
 *       2.2.1 在该Activity中动态添加一个Fragment显示详细信息
 *
 * 参考文档:
 * 1 http://blog.csdn.net/t12x3456/article/details/8120309
 * 2 http://blog.csdn.net/nkmnkm/article/category/958669/5
 * 3 http://blog.csdn.net/xiaanming/article/details/9254749
 *   Thank you very much
 *
 */
public class MainActivity extends Activity {
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		System.out.println("---> MainActivity onSaveInstanceState()");
	}

}

TitleListFragment如下:

package cc.testsimplefragment2;

import android.app.FragmentTransaction;
import android.app.ListFragment;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class TitleListFragment extends ListFragment {
	//当前是否为横屏
	private boolean currentIsLand;
	//当前选中位置
	private int currentCheckedPosition = -1;
	private final String currentCheckedKey="currentChecked";

	//每次重绘Fragment时都会调用该onActivityCreated()方法
	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
        System.out.println("---> onActivityCreated");
		//设置适配器
		ArrayAdapter<String> arrayAdapter=
		new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_checked, Data.TITLES);
		setListAdapter(arrayAdapter); 

		//判断当前是否为横屏
		//注意方式:
		//先利用getActivity()找到该Fragment隶属于的Activity,再findViewById()
		//为什么要这么判断是否是横屏呢?
		//因为横屏的时候会去读取layout-land下的main.xml布局文件
		//在该布局文件下有一个RelativeLayout,其id为containerRelativeLayout
		//所以,若能找到它那么就可以表明当前是横屏
		View containerView = getActivity().findViewById(R.id.containerRelativeLayout);
		currentIsLand = containerView != null && containerView.getVisibility() == View.VISIBLE; 

		if (savedInstanceState != null) {
			currentCheckedPosition = savedInstanceState.getInt(currentCheckedKey, 0);
			getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
			getListView().setItemChecked(currentCheckedPosition, true);
			System.out.println("---> onActivityCreated() currentCheckedPosition="+currentCheckedPosition);
		}else{
			System.out.println("---> onActivityCreated() savedInstanceState == null ");
		}

		if (currentIsLand) {
			//设置ListView为单选模式
			getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
			showDetailContent(currentCheckedPosition);
		}
	}

	@Override
	public void onStart() {
		super.onStart();
		System.out.println("---> onStart");
	}

	//处理手机一直在竖屏时:
	//点击标题,跳转后,再按下back键的情况
	@Override
	public void onResume() {
		super.onResume();
		System.out.println("---> onResume");
		if (!currentIsLand) {
			getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
			//currentCheckedPosition默认为-1
			//所以在第一次时不选择任何一个
			if (currentCheckedPosition>=0) {
				getListView().setItemChecked(currentCheckedPosition, true);
			}
		}
	}

	//保存数据
	//Fragment被系统或者某些内存清理,或者横竖屏切换而被销毁时
	//将会触发onSaveInstanceState(Bundle savedInstanceState):
	//Called to ask the fragment to save its current dynamic state,
	//so it can later be reconstructed in a new instance of its process is restarted.
	//然后调用onActivityCreated()生命周期方法,重绘Fragment

	//存在的疑问:
	//在手机一直竖屏的情况下,点击TitleListFragment的条目
	//为什么会执行该onSaveInstanceState()方法和MainActivity的
	//onSaveInstanceState()方法
	@Override
	public void onSaveInstanceState(Bundle bundle) {
		super.onSaveInstanceState(bundle);
		bundle.putInt(currentCheckedKey, currentCheckedPosition);
		System.out.println("---> onSaveInstanceState()");
		System.out.println("---> onSaveInstanceState() currentCheckedPosition="+currentCheckedPosition);
	}

	//点击ListFragment上的某个条目时调用
	@Override
	public void onListItemClick(ListView l, View v, int position, long id) {
		showDetailContent(position);
	}

	//显示详细内容
	private void showDetailContent(int index) {
		//保存当前被选中的位置
		currentCheckedPosition=index;
		//横屏时
		if (currentIsLand) {
			//1  先设置TitleListFragment
			//  改变ListFragment的index位置被选中
			getListView().setItemChecked(index, true); 

			//2  再设置DetailFragment
			//  利用FragmentManager判断在某个容器(container)中是否有一个DetailFragment
			//  如果没有或在有的情况下其CheckedIndex不等于当前被选中的index
			//  则进行replace()操作
			DetailFragment detailFragment =
			(DetailFragment) getFragmentManager().findFragmentById(R.id.containerRelativeLayout);
			if (detailFragment == null || detailFragment.getCheckedIndex() != index) {
				//生成新的Fragment.
				detailFragment = DetailFragment.newInstance(index);
				//开始Fragment的事务Transaction
				//因为在这个事务中执行了replace()操作,所以会将该
				//detailFragment attach到activity,按照生命周期
				//的顺序必然会调用DetailFragment的onCreateView().
				//更加白话地说:其实相当于我们先做了一些内在的东西,再做了外在的东西.
				//什么意思呢?
				//内在的部分:我们先new了一个DetailFragment,并且为这个DetailFragment
				//设置了一些参数.
				//这些都体现在了DetailFragment.newInstance(index)方法中
				//外在的部分:利用replace()将该DetailFragment attach到activity
				//这些都体现在了DetailFragment的onCreateView()方法中.所以在
				//该方法中我们可以去取为此DetailFragment设置的参数.
				//即方法getCheckedIndex()
				FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
				//替换容器(container)原来的Fragment
				fragmentTransaction.replace(R.id.containerRelativeLayout, detailFragment);
				//设置转换效果
				fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
				//提交事务
				fragmentTransaction.commit();
			}
        //竖屏时
		} else {
			Intent intent = new Intent(getActivity(),DetailActivity.class);
			intent.putExtra("index", index);
			startActivity(intent);
		}
	}

}

DetailFragment如下:

package cc.testsimplefragment2;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ScrollView;
import android.widget.TextView;

public class DetailFragment extends Fragment {

	//往ScrollView中添加一个TextView然后将其返回
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
		if (container == null) {
			return null;
		}
		ScrollView scrollView = new ScrollView(getActivity());
		TextView textView = new TextView(getActivity());
		textView.setPadding(10, 10, 10, 10);
		scrollView.addView(textView);
		textView.setText(Data.DETAILS[getCheckedIndex()]);
		return scrollView;
	}

	//生成DetailFragment实例,并且保存index
	public static DetailFragment newInstance(int index) {
		DetailFragment detailFragment = new DetailFragment();
		Bundle bundle = new Bundle();
		bundle.putInt("index", index);
		detailFragment.setArguments(bundle);
		return detailFragment;
	}

	//取出index
	public int getCheckedIndex() {
		int index =getArguments().getInt("index", 0);
		return  index;
	}
}

DetailActivity如下:

package cc.testsimplefragment2;
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
/**
 * 在此Activity中我们将一个Fragment嵌入到
 * 该Activity中进行显示
 */
public class DetailActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//横屏的处理
		if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
			finish();
			return;
		}

		//竖屏的处理
		//此处的道理和TitleListFragment中对于横屏的
		//处理很相似,只是方式稍有差别.
		//1 生成设置好参数的DetailFragment
		//2 将此DetailFragment attach到当前的activity
		if (savedInstanceState == null) {
			DetailFragment detailFragment = new DetailFragment();
			detailFragment.setArguments(getIntent().getExtras());
			getFragmentManager()
			.beginTransaction()
			.add(android.R.id.content, detailFragment)
			.commit();
		}
	}
}

Data如下:

package cc.testsimplefragment2;
public final class Data {
	//标题
    public static final String[] TITLES = { "标题1","标题2", "标题3","标题4"};
    //内容
    public static final String[] DETAILS = { "内容1","内容2", "内容3","内容4"};
}

layout/main.xml如下:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="horizontal"
	android:layout_width="match_parent"
	android:layout_height="match_parent">

	<fragment
		android:id="@+id/titles"
		class="cc.testsimplefragment2.TitleListFragment"
		android:layout_weight="1"
		android:layout_width="0px"
		android:layout_height="match_parent" />

</LinearLayout>

 

layout-land/main.xml如下:

<?xml version="1.0" encoding="utf-8"?>
<!-- 横屏时的布局文件 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="horizontal"
	android:layout_width="match_parent"
	android:layout_height="match_parent">

	<fragment
		android:id="@+id/titles"
		class="cc.testsimplefragment2.TitleListFragment"
		android:layout_weight="1"
		android:layout_width="0px"
		android:layout_height="match_parent"
     />

	<RelativeLayout
	    android:id="@+id/containerRelativeLayout"
		android:layout_weight="2"
		android:layout_width="0px"
		android:layout_height="match_parent"
		android:background="?android:attr/detailsElementBackground"
	 />

</LinearLayout>

AndroidManifest.xml如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cc.testsimplefragment2"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name="cc.testsimplefragment2.MainActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

	   <activity
	       android:name="cc.testsimplefragment2.DetailActivity"
	       android:label="详细内容的Activity"
       />

    </application>

</manifest>

 

时间: 2024-10-21 21:33:05

Fragment详解(三)---&gt;横竖屏幕切换完整示例的相关文章

ViewPager详解(一)——ViewPager的基本使用完整示例

MainActivity如下: package cn.ww; import java.lang.reflect.Field; import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.support.v4.view.ViewPager; import android.support.v4.widget.EdgeEffectCompat; import

Android开发 Activity和Fragment详解_Android

1.Activity的生命周期 1)多个Activity组成Activity栈,当前活动位于栈顶.我们先来看看各种Activity基类的类图: 当Activity类定义出来之后,这个Activity何时被实例化.它所包含的方法何时被调用,这些都不是由开发者所决定的,都应该由Android系统来决定. 下面我们来看一下Activity的生命周期: 2.Activity的用法 1)启动.关闭Activity // 首先需要创建启动的Activity对应的Intent Intent intent =

Android的ToDoList(fragment) 详解

Fragment(碎片) 可以灵活地从一个活动的Activity上添加或删除Fragment, 有良好的用户体验; 下面是Fragment的具体设计: 1. 创建new_item_fragment的资源文件: 位置: res->new_item_fragment.xml <?xml version="1.0" encoding="utf-8"?> <EditText xmlns:android="http://schemas.and

Masonry自动布局详解三:remake约束

Masonry自动布局详解三:remake约束 说到iOS自动布局,有很多的解决办法.有的人使用xib/storyboard自动布局,也有人使用frame来适配.对于前者,笔者并不喜欢,也不支持.对于后者,更是麻烦,到处计算高度.宽度等,千万大量代码的冗余,对维护和开发的效率都很低. 笔者在这里介绍纯代码自动布局的第三方库:Masonry.这个库使用率相当高,在全世界都有大量的开发者在使用,其star数量也是相当高的. 支持原创,请阅读原文 效果图 本节详解Masonry的以动画的形式更新约束的

Android横竖屏幕切换小结_Android

Android手机或平板都会存在横竖屏切换的功能,通常是由物理重力感应触发的,但是有时候也不尽然,通常在设置里面我们可以对手机的横竖屏切换进行关闭. AndroidManifest.xml <activity android:name="com.google.android.gms.ads.AdActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|

第七篇Bootstrap表单布局实例代码详解(三种表单布局)_javascript技巧

Bootstrap提供了三种表单布局:垂直表单,内联表单和水平表单.下面逐一给大家介绍,有兴趣的朋友一起学习吧. 创建垂直或基本表单: •·向父 <form> 元素添加 role="form". •·把标签和控件放在一个带有 class .form-group 的 <div> 中.这是获取最佳间距所必需的. •·向所有的文本元素 <input>.<textarea> 和 <select> 添加 class .form-cont

Android横竖屏幕切换生命周期详解

一.简介 二.代码 /activityLifeCycle_3Screen/AndroidManifest.xml <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.fry.activityLifeCycle_3Screen" android:versionCode="1" android:versionName="1.

Netty4详解三:Netty架构设计

     读完这一章,我们基本上可以了解到Netty所有重要的组件,对Netty有一个全面的认识,这对下一步深入学习Netty是十分重要的,而学完这一章,我们其实已经可以用Netty解决一些常规的问题了. 一.先纵览一下Netty,看看Netty都有哪些组件?      为了更好的理解和进一步深入Netty,我们先总体认识一下Netty用到的组件及它们在整个Netty架构中是怎么协调工作的.Netty应用中必不可少的组件: Bootstrap or ServerBootstrap EventLo

kafka详解三:开发Kafka应用

一.整体看一下Kafka 我们知道,Kafka系统有三大组件:Producer.Consumer.broker . producers 生产(produce)消息(message)并推(push)送给brokers,consumers从brokers把消息提取(pull)出来消费(consume). 二.开发一个Producer应用          Producers用来生产消息并把产生的消息推送到Kafka的Broker.Producers可以是各种应用,比如web应用,服务器端应用,代理应