본문 바로가기

구글과인터넷/안드로이드

안드로이드 플레그먼트 레이아웃 관련

출처: http://susemi99.tistory.com/1095

fragment 에 대한 설명 : http://androidhuman.tistory.com/469

예제 소스는 http://daddycat.blogspot.com/2011/08/android-30-fragments-example.html 에서 가져와서 약간 수정했음.

허니컴 이하에서 사용할 때 주의할 점 : http://www.androidpub.com/1432908


근데 원래 이 기능은 허니컴부터 지원하는 기능이여서, 2.2에서 사용하려면 좀 더 해줘야한다.

File - Properties - Java Build Path - Libraries - Add External JARs... - ~/sdk/extras/android/support/v4/android-support-v4.jar 선택
 









main.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?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="horizontal" >
    <fragment
        android:id="@+id/titles"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        class="kr.mint.testfragment.menuFragment" /> <!-- 고정된 클래스를 사용할 때 -->
    <FrameLayout
        android:id="@+id/details"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>


다음은 화면 왼쪽에 나타 낼  fragment를 생성한다.

menuFragment.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
 
public class menuFragment extends Fragment
{
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View view = inflater.inflate(R.layout.menu_fragment, null);
         
        Button naver = (Button) view.findViewById(R.id.naver);
        Button daum = (Button) view.findViewById(R.id.daum);
        Button google = (Button) view.findViewById(R.id.google);
        Button yahoo = (Button) view.findViewById(R.id.yahoo);
         
        naver.setOnClickListener(onBtnClickListener);
        daum.setOnClickListener(onBtnClickListener);
        google.setOnClickListener(onBtnClickListener);
        yahoo.setOnClickListener(onBtnClickListener);
         
        showDetailFragment("m.nate.com");
         
        return view;
    }
     
     
    private void showDetailFragment(String $url)
    {
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        Fragment newFragment;
         
        // url에 naver가 들어가면 테스트용 화면을 불러온다
        if ($url.indexOf("naver") > -1)
        {
            newFragment = new naverFragment();
        }
        else
        {
            newFragment = detailFragment.newInstance($url);
        }
         
        ft.replace(R.id.details, newFragment);
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
        ft.commit();
    }
     
    private OnClickListener onBtnClickListener = new OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            showDetailFragment(v.getTag().toString());
        }
    };
}

menu_fragment.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#ff0000">
 
    <Button
        android:id="@+id/naver"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:tag="m.naver.com"
        android:text="naver" />
 
    <Button
        android:id="@+id/daum"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:tag="m.daum.net"
        android:text="daum" />
 
    <Button
        android:id="@+id/google"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:tag="m.google.com"
        android:text="google" />
 
    <Button
        android:id="@+id/yahoo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:tag="w.yahoo.co.kr"
        android:text="yahoo" />
 
</LinearLayout>


그 다음은 웹화면을 보여줄 fragment  화면을 추가한다.

detailFragment.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.CookieSyncManager;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
 
public class detailFragment extends Fragment
{
    private static final String KEY_URL = "url";
     
     
    public static detailFragment newInstance(String index)
    {
        detailFragment f = new detailFragment();
         
        Bundle args = new Bundle();
        args.putString(KEY_URL, index);
        f.setArguments(args);
         
        return f;
    }
     
     
    public String getShownIndex()
    {
        // String result = "m.nate.com";
        String result = getArguments().getString(KEY_URL);
        Log.e("###""url : " + result);
        return result;
    }
     
     
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        return inflater.inflate(R.layout.detail_fragment, null);
    }
     
     
    @Override
    public void onActivityCreated(Bundle savedInstanceState)
    {
        super.onActivityCreated(savedInstanceState);
         
        WebView browser = (WebView) getActivity().findViewById(R.id.mainWebkit);
        browser.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
        browser.setWebViewClient(new MainWebViewClient());
        WebSettings ws = browser.getSettings();
        ws.setJavaScriptEnabled(true);
        ws.setDefaultZoom(WebSettings.ZoomDensity.FAR);
        browser.requestFocusFromTouch();
        browser.loadUrl("http://" + getShownIndex());
    }
     
    private class MainWebViewClient extends WebViewClient
    {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url)
        {
            view.loadUrl(url);
            return true;
        }
         
         
        @Override
        public void onPageFinished(WebView view, String url)
        {
            CookieSyncManager.getInstance().sync();
        }
    }
}

detail_fragment.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
<?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" >
 
    <WebView
        android:id="@+id/mainWebkit"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scrollbars="none" />
 
</LinearLayout>



그냥 이것만 하면 밋밋하니까 양념으로 버튼이 들어가있는 화면 하나를 더 만들어서 클릭 이벤트를 만들어보자 


naverFragment.java.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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.Button;
 
public class naverFragment extends Fragment
{
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View view = inflater.inflate(R.layout.naver_fragment, null);
         
        final Button btn1 = (Button)view.findViewById(R.id.button1);
        btn1.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                btn1.setText("aaaaaaaaaa");
            }
        });
         
        return view;
    }
}

naver_fragment.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?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" >
 
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />
 
    <CheckBox
        android:id="@+id/checkBox1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CheckBox" />
 
    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge" />
 
</LinearLayout>



여기까지 했으면 얼추 다 된건데, 그냥 실행하면 이런 에러가 난다.

error
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
java.lang.RuntimeException: Unable to start activity ComponentInfo{kr.mint.testfragment/kr.mint.testfragment.Home}: android.view.InflateException: Binary XML file line #6: Error inflating class fragment
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1751)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1767)
    at android.app.ActivityThread.access$1500(ActivityThread.java:122)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1005)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:132)
    at android.app.ActivityThread.main(ActivityThread.java:4028)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:491)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: android.view.InflateException: Binary XML file line #6: Error inflating class fragment
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:688)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:724)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:479)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:391)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:347)
    at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:245)
    at android.app.Activity.setContentView(Activity.java:1780)
    at kr.mint.testfragment.Home.onCreate(Home.java:13)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1048)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1715)
    ... 11 more
Caused by: java.lang.ClassCastException: kr.mint.testfragment.menuFragment cannot be cast to android.app.Fragment
    at android.app.Fragment.instantiate(Fragment.java:493)
    at android.app.Fragment.instantiate(Fragment.java:468)
    at android.app.Activity.onCreateView(Activity.java:4132)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:664)
    ... 20 more


그래서 메인 액티비티의 부모 클래스를 FragmentActivity로 바꿔줘야한다. 
Home.java
1
2
3
4
5
6
7
8
9
10
11
12
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
 
public class Home extends FragmentActivity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}



다음 홈페이지



 




네이버를 눌렀을 때는 버튼이 있는 화면을 보여준다.




인터넷을 써야하니까 
AndroidManifest.xml 에 추가
1
<uses-permission android:name="android.permission.INTERNET">
을 추가해야 한다.


예제 소스 다운받기 


///////////////////////////////////////////////////////////////////////////////////


출처: http://daddycat.blogspot.com/2011/08/android-30-fragments-example.html

Android 3.0 Fragments Example


Fragment을 적용한 Sample App을 만들어보기로 하겠습니다.

App의 형태는 아래와 같습니다.
  1. 좌측은 메뉴 형태로 각 사이트로 이동할 수 있는 버튼이 4개 있습니다.
  2. 버튼을 클릭하면 우측 Webview가 해당 사이트로 이동합니다.
  3. 처음 시작은 m.nate.com 에서 시작됩니다.





위 화면을 구성하기 위해서는 외곽을 구성하는 하나의 Activity와 두 개의 Fragment을 작성해야 합니다.







Step 1: AndroidMainfest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.daddycat.fragment"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="12" />

<application
android:icon="@drawable/icon"
android:label="@string/app_name">
<activity
android:name=".FirstFragmentsLayoutActivity"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

</application>
<supports-screens
android:largeScreens="true"
android:normalScreens="true"
android:anyDensity="true" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>

Step 2:  Activity을 구성하는 default_fragment_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<fragment
android:id="@+id/menu"
class="com.daddycat.fragment.FirstFragmentsLayoutActivity$menuFragment"
android:layout_width="400px"
android:layout_height="fill_parent" />


<FrameLayout
android:id="@+id/details"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="?android:attr/detailsElementBackground" />
</LinearLayout>

Step 3: Menu Fragment Layout, menu_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#bbbbbb">


<Button
android:id="@+id/naver"
android:layout_width="150px"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="네이버"
android:tag="m.naver.com" />


<Button
android:id="@+id/daum"
android:layout_width="150px"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="다음"
android:tag="m.daum.net" />


<Button
android:id="@+id/google"
android:layout_width="150px"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="구글"
android:tag="m.google.com" />


<Button
android:id="@+id/yahoo"
android:layout_width="150px"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="야후"
android:tag="w.yahoo.co.kr" />

</LinearLayout>

Step 4: Detail Fragment Layout, detail_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<WebView
android:id="@+id/mainWebkit"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbars="none" />

</LinearLayout>

Step 5: Activity & Fragments, FirstFragmentsLayoutActivity.java
package com.daddycat.fragment;

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.webkit.CookieSyncManager;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;

public class FirstFragmentsLayoutActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.default_fragment_layout);

}

public static class menuFragment extends Fragment {
boolean mDualPane;
private Button naver;
private Button daum;
private Button google;
private Button yahoo;

@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);

naver = (Button) getActivity().findViewById(R.id.naver);
daum = (Button) getActivity().findViewById(R.id.daum);
google = (Button) getActivity().findViewById(R.id.google);
yahoo = (Button) getActivity().findViewById(R.id.yahoo);

naver.setOnClickListener(new MenuOnClickListener());
daum.setOnClickListener(new MenuOnClickListener());
google.setOnClickListener(new MenuOnClickListener());
yahoo.setOnClickListener(new MenuOnClickListener());

View detailsFrame = getActivity().findViewById(R.id.details);
mDualPane = detailsFrame != null
&& detailsFrame.getVisibility() == View.VISIBLE;
showDetailFragment("m.nate.com");
}

private void showDetailFragment(String index) {
if (mDualPane) {
DetailsFragment details = (DetailsFragment) getFragmentManager()
.findFragmentById(R.id.details);
details = DetailsFragment.newInstance(index);
FragmentTransaction ft = getFragmentManager()
.beginTransaction();
ft.replace(R.id.details, details);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
}
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.menu_fragment, null);
}

private class MenuOnClickListener implements OnClickListener {

@Override
public void onClick(View v) {

showDetailFragment(v.getTag().toString());
}

}
}

public static class DetailsFragment extends Fragment {

public static DetailsFragment newInstance(String index) {
DetailsFragment f = new DetailsFragment();

Bundle args = new Bundle();
args.putString("index", index);
f.setArguments(args);

return f;
}

public String getShownIndex() {
return getArguments().getString("index", "m.nate.com");
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.detail_fragment, null);
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);

WebView browser = (WebView) getActivity().findViewById(
R.id.mainWebkit);
browser.setWebViewClient(new MainWebViewClient());
WebSettings ws = browser.getSettings();
ws.setJavaScriptEnabled(true);
ws.setDefaultZoom(WebSettings.ZoomDensity.FAR);
browser.requestFocusFromTouch();
boolean ScrollBarEnabled = getActivity().getIntent()
.getBooleanExtra("ScrollBarEnabled", true);
if (!ScrollBarEnabled) {
browser.setVerticalScrollBarEnabled(false);
browser.setHorizontalScrollBarEnabled(false);
}
browser.loadUrl("http://" + getShownIndex());
}

private class MainWebViewClient extends WebViewClient {

@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {

view.loadUrl(url);
return true;
}

@Override
public void onPageFinished(WebView view, String url) {
CookieSyncManager.getInstance().sync();

}
}
}
}


///////////////////////////////////////////////////////////////////////////////////

관련 링크

http://daddycat.blogspot.com/2011/08/android-30-fragments-example.html

http://susemi99.tistory.com/1095

http://www.androidpub.com/1432908