1. 程式人生 > >Fragment同時適配手機和平板兩種螢幕

Fragment同時適配手機和平板兩種螢幕

       Fragment對於Android開發來說,是一個必不可少的工具,我們使用這個工具可以輕鬆應對很多介面管理上的問題,例如如何分屏,如何移除介面和替換介面等。更為神奇的是,我們可以結合Android系統的特性和Fragment來實現一個工程適應手機平板兩種螢幕。當然這需要我們在程式碼中進行一點判斷。現在,通過下面這個例子我們來了解一下如何用同一個工程來適應手機和平板的。

      首先,我們需要看一下目錄結構,這次的目錄結構要比前兩次的目錄複雜一些。主要原因是這次除了需要主Activity的佈局之外還需要Fragment的佈局。

         

       要看出平板和手機的效果需要兩個Fragment,這樣如果是手機的話就會從一個Fragment跳轉到另一個Fragment,如果是平板的話就會在同一個螢幕上顯示出兩個Fragment。

       這裡實現依賴Android系統的限定符,也就是類似layout-land的形式,“-”後面跟的就是限定符,限定符是用來提示系統需要載入內容的,比如這裡,如果是橫向的螢幕時就會載入這裡的佈局檔案。

      接下來奉上詳細程式碼,因為是手機和平板兩個版本,所以會有兩個Activity佈局。

手機版佈局:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    
    <!-- 裝載列表的Fragment 的容器 -->
    <LinearLayout 
        android:id="@+id/list_container"
        android:orientation="vertical"
        android:layout_width="match_parent"
  		android:layout_height="match_parent">
    </LinearLayout>
    
    
    <!-- 裝載詳情的Fragment 的容器 -->
    <LinearLayout 
        android:id="@+id/detail_container"
        android:orientation="vertical"
        android:layout_width="match_parent"
  	android:layout_height="match_parent">
    </LinearLayout>

</FrameLayout>

      這是在一個FrameLayout下放置了兩個LinearLayout,分別用來裝載兩個Fragment。

平板版佈局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    
    <!-- 裝載列表的Fragment 的容器 -->
    <LinearLayout 
        android:id="@+id/list_container"
        android:orientation="vertical"
        android:layout_width="match_parent"
  	android:layout_height="match_parent"
  	android:layout_weight="2">
    </LinearLayout>
    
    
    <!-- 裝載詳情的Fragment 的容器 -->
    <LinearLayout 
        android:id="@+id/detail_container"
        android:orientation="vertical"
        android:layout_width="match_parent"
  	android:layout_height="match_parent"
  	android:layout_weight="1">
    </LinearLayout>

</LinearLayout>

        可能有人覺得這裡乍一看,兩個佈局沒什麼區別啊。但是,請不要乍一看就下結論,這裡其實是有區別的,而且是比較大的區別,看根標籤就能看出來,手機版的是一個FrameLayout,而平板版的佈局是一個LinearLayout。而且平板佈局是有分權重的。這就是列表和詳情頁所佔螢幕比例不同的原因。

       好了有了佈局之後就可以寫Activity部分的內容了。接下來看Activity的程式碼。

package com.example.fragmentdemo;

import com.example.fragmentdemo3.R;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;

public class MainActivity extends FragmentActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		//建立一個左側列表的Fragment
		Fragment listFragment = new FragmentLeft();
		
		//得到一個管理器,用來管理Fragment
		FragmentManager fragmentManager = getSupportFragmentManager();
		//用FragmentManager開啟一個Fragment事務
		FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
		//把剛建立的列表放到列表容器裡
		fragmentTransaction.add(R.id.list_container, listFragment);
		
		//記得提交
		fragmentTransaction.commit();
	}	

}


       Activity裡的程式碼十分簡單,不過需要注意的是這裡繼承的不是普通的Activity,而是一個FragmetActivity,接下來和普通的Activity一樣,我們需要為Activity設定佈局檔案,設定完成佈局檔案之後就是,管理在這個Activity上的Fragment了。先新建一個Fragment,然後得到一個Fragment的管理器。得到管理器之後還需要開啟一個Fragment的事務,聽起來似乎有些麻煩,但實際上程式碼就那麼幾行。

      最後用add方法把剛才建立的列表Fragment裝到列表容器裡,也就是佈局檔案裡的Layout裡。提交事務就即可。

      只有一個Fragment是看不出效果的,需要建立兩個才行,否則螢幕是一個,Fragment也是一個,無法判斷手機螢幕是否跳轉,平板螢幕是否分屏。

      所以,接下來,建立兩個Fragment,大家都知道,Fragment也是有自己佈局的,實際上Fragment和一個小型的Fragment差不多,Fragment也有自己的生命週期。

剛才Activity裡用到了列表頁的Fragment,我們先看列表頁的Fragment。

package com.example.fragmentdemo;

import java.util.ArrayList;
import java.util.List;

import com.example.fragmentdemo3.R;

import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentManager.OnBackStackChangedListener;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

/**
 * 
 * @author yufc
 *
 */
public class FragmentLeft extends Fragment {
	
	private List<String> leftList = new ArrayList<String>();


	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		return inflater.inflate(R.layout.fragment_left_layout, container, false);
	}
	
	
	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		
		//左側ListView
		for(int i=0, count=20; i<count; i++){
			leftList.add("這是第" + i+"條資料");
		}
		
		//取到ListView
		ListView listView = (ListView) getActivity().findViewById(R.id.fragment_list);
		listView.setAdapter(new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, leftList));
		
		listView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				//得到一個新的Fragment,作為右側的Fragment
				Fragment rightFragment = new FragmentRight();
				
				//傳遞顯示資料
				Bundle mBundle = new Bundle();
				mBundle.putString("arg", leftList.get(position));
				rightFragment.setArguments(mBundle);
				
				//建立一個Fragment的管理器
				final FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
				final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
				
				//判斷橫豎屏
				Configuration configuration = getActivity().getResources().getConfiguration();
				int ori = configuration.orientation;
				
				fragmentTransaction.replace(R.id.detail_container, rightFragment);
				
				//這裡是為了讓Fragment可以回退,不至於直接退出Activity
				if(ori == configuration.ORIENTATION_PORTRAIT){
					fragmentTransaction.addToBackStack(null);
				}
				
				fragmentTransaction.commit();
				
				
			}
		});
		
	}
	
	/**
	 * 
	 * @param msg
	 */
	private void showTost(String msg){
		Toast.makeText(getActivity(), msg, Toast.LENGTH_LONG).show();
	}

}

當然少不了為這個Fragment寫一個佈局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ff00ff99"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/fragment_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:cacheColorHint="@android:color/transparent"
        android:fadingEdge="none" >
    </ListView>

</LinearLayout>
佈局很簡單,LinearLayout裡有一個ListView。

    這裡Java程式碼有點長,但並不難理解。既然要建立一個Fragment,與要建立一個Activity的思路是相似的,建立Activity需要繼承Activity類,同樣建立一個Fragment需要繼承Fragment類。之後需要複寫Fragment的方法,這裡複寫的是onCreateView方法,在這個方法裡需要對Fragment的佈局初始化。方法就是用inflate方法。Fragment的生命週期是繫結在Activity上的,所以還需要複寫一個OnActivityCreate方法,當Activity建立時進行一些必要的操作。
     在OnActivityCreate方法裡,需要得到佈局檔案裡的ListView,顯示內容,設定一些資料也是必要的,這裡只是用一個迴圈設定了一些資料,用一個最簡單的Adapter來裝載這些資料。接下來設定ListView的點選事件,點選完列表的條目之後自然是要顯示詳情,這裡和Activity裡相似,建立詳情Fragment。這裡不再贅述。

     相對來說詳情Fragment就要簡單多了。和列表相比簡單到幾乎沒有什麼內容,只是簡單的得到列表頁裡傳來的資料,顯示出來而已。下面是詳情Fragment的程式碼。

詳情Fragment的Layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#ff006600" >

    <ListView
        android:id="@+id/fragment_detail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:cacheColorHint="@android:color/transparent"
        android:fadingEdge="none" >
    </ListView>

</LinearLayout>

也是LinearLayout下有一個ListView。

然後是Java程式碼

package com.example.fragmentdemo;

import java.util.ArrayList;
import java.util.List;

import com.example.fragmentdemo3.R;

import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;

/**
 * 
 * @author yufc
 *
 */
public class FragmentRight extends Fragment {

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		return inflater.inflate(R.layout.fragment_right_layout, container, false);
	}
	
	
	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		
		//取出前一個Fragment傳來的資料
		Bundle bundle = getArguments();
		String data = bundle.getString("arg");
		
		List<String> list = new ArrayList<String>();
		for(int i=0, count=20; i<count; i++){
			list.add(data);
		}
		
		LinearLayout layout = (LinearLayout) getActivity().findViewById(R.id.detail_container);
		
		ListView listView = (ListView) getActivity().findViewById(R.id.fragment_detail);
		listView.setAdapter(new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, list));
		
		
	
	}

}


好了,大致就是這個樣子了。

下面是Manifest檔案

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

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="16" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.fragmentdemo.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

點選下載程式碼

相關推薦

Fragment同時手機平板螢幕

       Fragment對於Android開發來說,是一個必不可少的工具,我們使用這個工具可以輕鬆應對很多介面管理上的問題,例如如何分屏,如何移除介面和替換介面等。更為神奇的是,我們可以結合Android系統的特性和Fragment來實現一個工程適應手機平板兩種螢幕

利用Fragment編寫簡易新聞介面,佈局同時適應Android手機平板電腦

        大家好,最近從事培訓工作碰到一個練習題,利用Fragment編寫簡易新聞介面,並且佈局能同時適應手機和平板電腦,這是書本上的一個練習題,題目本身沒多大難度,個人覺得作者程式碼的模組化做得比較好,所以拿出來分享,同時自己學習也複習、鞏固一下。        

runtime 替換系統 imageNamed 方法,同時iphoneipad圖片

建立 UIImage 分類 UIImage+Category.h #import <UIKit/UIKit.h> #define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) #defin

Android手機平板螢幕尺寸

一.劃分手機和平板 人為判斷方法: 大於6英寸的就是平板。小於6英寸的都是手機 平板尺寸: 6英寸、7英寸、10英寸、14英寸… Android系統支援多配置資原始檔,我們可以追加新的資源目錄到你的Android專案中。命名規範: 資源

手機端的幾寫法

1,rem佈局,現在普遍常用的方法 一般ui設計師給的頁面都是640的,所以document.documentElement.clientWidth/6.4+"px";專案中,在ps中量的尺寸直接除以

Android手機平板不誤,使用Fragment實現相容手機平板的程式

記得我之前參與開發過一個華為的專案,要求程式可以支援好幾種終端裝置,其中就包括Android手機和Android Pad。然後為了節省人力,公司無節操地讓Android手機和Android Pad都由我們團隊開發。當時專案組定的方案是,製作兩個版本的App

Nginx配置站點PC手機

for 服務端 roi text pro str fly ora 打開 考慮到站點的在多種設備下的兼容性,有非常多站點會有手機版和電腦版兩個版本號。訪問同一個站點URL,當服務端識別出用戶使用電腦訪問。就打開電腦版的頁面,用戶假設使用手機訪問,則會得到手機版的頁面。1、

讓一份程式同時適應手機平板,動態載入佈局的技巧

  由於平板電腦的螢幕足夠大,我們會發現很多應該採用了雙頁模式即程式在左側面板上顯示一個包含子項的列表,右側面板顯示內容,而手機螢幕一次只能顯示一頁內容,因此兩個頁面需要分開顯示。   為了讓碎片發揮

Nginx配置網站PC手機

考慮到網站的在多種裝置下的相容性,有很多網站會有手機版和電腦版兩個版本。訪問同一個網站URL,當服務端識別出使用者使用電腦訪問,就開啟電腦版的頁面,使用者如果使用手機訪問,則會得到手機版的頁面。 1、判斷客戶端的裝置型別 要想讓網站適配PC和手機裝置,首先要能做出準確的

51CTO博客發布H5移動版(手機)2017.5.17

51cto博客 移動站 各位,51CTO博客於5月17日發布H5移動版,可以適配手機和平板,分享文章到手機,閱讀體驗更佳,掃碼可以進入(進入後,可以收藏到瀏覽器或展示在手機桌面,以後可以打開進入博客): 後續我們還會繼續優化移動站的首頁,也歡迎廣大博友的建議和意見。51CTO博客發布H5移

Android 多屏幕 dppx的關系 最好用dp

linear title url -h pre ref end 建議 限制 Android 多屏幕適配 dp和px的關系 一直以來別人經常問我,android的多屏幕適配到底是怎麽弄,我也不知道如何講解清楚,或許自己也是挺迷糊。 以下得出的結論主要是結合官方文檔進行分析

7個步驟讓PC網站自動手機網頁

on() 開發 應用 網頁 con 像素 取消 ica 引入 傳統的網站如何完成向移動設備的快速轉型? 通過移動適配技術可以實現,切圖網是國內首家基於web技術服務的公司,而移動適配主要通過底層的web技術開發手段來完成,下面切圖網將從技術角度來告訴你通過7個步驟來完成一個

淺析Android Camera開發中的三個尺寸變形 貢獻一個自PicturesizePreviewsiz

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

react滾動條開發 PC 移動端的滾動 顯示隱藏headerfooter/滾動顯隱公用元件

功能描述: 移動端時,上滾則顯示footer,下滾則隱藏footer PC端時,上滾則顯示header,下滾則隱藏header。 xx.js import React, { Component } from 'react'; import { BrowserR

Android學習第7篇——碎片實踐,結合ListView的簡單閱讀應用,自適應手機平板

在學過了碎片(Fragment)、ListView之後,實現一個自適應手機和平板的文章閱讀應用效果圖:手機: 平板:二、實現過程:1、新建一個文章實體類Newspublic class News { private String title; private

移動端頁面remvw的使用轉換

物理畫素:dp、比如蘋果7主屏解析度:1334dp*750dp 邏輯畫素:px、開發中用到的畫素 畫素縮放比:dpr、物理畫素跟邏輯畫素之間的比例關係 畫素密度:ppi、螢幕每英寸畫素密度【√(133

移動端JSCSS

移動端適配一般是兩種方式一JS方式:setRem(); window.addEventListener("orientationchange", setRem); window.addEventListener("resize", setRem); functio

HTML頁面手機移動端視窗寬度

         隨著網路的快熟發展,越來越多的人使用手機上網。移動裝置正超過桌面裝置,成為訪問網際網路的最常見終端。於是,網頁設計師不得不面對一個難題:如何才能在不同大小的裝置上呈現同樣的網頁?手機的

vue移動端的remvw記錄

在接觸移動端開發的時候,適配是必須要解決的一個問題。個人在開發過程中,也是邊做邊學,使用了一些常用的解決方案,這裡一一列舉出來: 前提:移動端的適配更多關注的是寬度的適配,也就是說元素在不同裝置上通過改變自身寬度來實現在頁面的比例一樣,這樣佈局就不會亂掉 1.百分比代替px

html5手機螢幕

<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=2.0, user-scalable=yes"