=======================
=======================
=======================
출처: http://itmir.tistory.com/283
맨 처음 어플을 만들게 되면서 가장 먼저 생각한 것은 바로 [탭, Tabs]이었습니다
무엇보다도 양옆으로 스크롤 하면서 사용할 수 있는 Fixed Tab + Scroll이 가장 마음에 들었는대요!
제가 네이버를 찾아보며 가장 설명이 잘되어 있는곳은 http://blog.naver.com/liar1938/30171663892 이라 생각됩니다
그러나 모든것은 직접 써봐야 더 능통해 지므로 서평이 끝난 지금, 지금부터 어플 강좌를 하나씩 시작하겠습니다~
이 강좌를 통해 알수 있는것들
Fragment
Fixed Tabs + Scroll
Fragment에서 id값 찾기
먼저 프로젝트를 만들어 주세요
Min API 11이상부터 Fixed Tabs + Swipe라는 네비게이션 타입을 지원하는것으로 알고있습니다
적절하게 잡아주시고
이렇게 Navigation Type를 "Fixed Tabs + Swipe"로 결정해 주세요 ㅎㅎ
프로젝트 생성이 끝났다면 이제 MainActivity에 들어가 봅시다
src/(패키지 네임)/MainActivity.java파일입니다
제 경험상
res/layout/activity_main.xml
res/layout/fragment_main_dummy.xml
이 두개의 파일은 건들일 필요가 없더군요
기본적으로 아래와 같은 내용이 있을겁니다 MainActivity을 눌러 펼쳐주세요
접기
package com.tistory.whdghks913.exampletabs;
import 생략
public class MainActivity extends FragmentActivity implements
ActionBar.TabListener {
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {@link android.support.v4.app.FragmentPagerAdapter} derivative, which
* will keep every loaded fragment in memory. If this becomes too memory
* intensive, it may be best to switch to a
* {@link android.support.v4.app.FragmentStatePagerAdapter}.
*/
SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {@link ViewPager} that will host the section contents.
*/
ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set up the action bar.
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Create the adapter that will return a fragment for each of the three
// primary sections of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(
getApplicationContext(), getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
// When swiping between different sections, select the corresponding
// tab. We can also use ActionBar.Tab#select() to do this if we have
// a reference to the Tab.
mViewPager
.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
// Create a tab with text corresponding to the page title defined by
// the adapter. Also specify this Activity object, which implements
// the TabListener interface, as the callback (listener) for when
// this tab is selected.
actionBar.addTab(actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void onTabSelected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
@Override
public void onTabReselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
/**
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
Context mContext;
public SectionsPagerAdapter(Context context, FragmentManager fm) {
super(fm);
mContext = context;
}
@Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a DummySectionFragment (defined as a static inner class
// below) with the page number as its lone argument.
Fragment fragment = new DummySectionFragment();
Bundle args = new Bundle();
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
return fragment;
}
@Override
public int getCount() {
// Show 3 total pages.
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.title_section1).toUpperCase(l);
case 1:
return getString(R.string.title_section2).toUpperCase(l);
case 2:
return getString(R.string.title_section3).toUpperCase(l);
}
return null;
}
}
/**
* A dummy fragment representing a section of the app, but that simply
* displays dummy text.
*/
public static class DummySectionFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
public static final String ARG_SECTION_NUMBER = "section_number";
public DummySectionFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main_dummy,
container, false);
TextView dummyTextView = (TextView) rootView
.findViewById(R.id.section_label);
dummyTextView.setText(Integer.toString(getArguments().getInt(
ARG_SECTION_NUMBER)));
return rootView;
}
}
}
접기
이 소스가 이 예제 어플에서 가장 중요한 소스입니다
먼저 처음 빨간색으로 칠해져 있는 메소드 public Fragment getItem(int position)의 경우 아래와 같이 변경이 필요합니다
@Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a DummySectionFragment (defined as a static inner class
// below) with the page number as its lone argument.
switch (position) {
case 0:
return new 첫번째탭에들어갈내용이담긴액티비티이름(mContext);
case 1:
return new 두번째탭에들어갈내용이담긴액티비티이름(mContext);
case 2:
return new 세번째탭에들어갈내용이담긴액티비티이름(mContext);
}
return null;
}
그런대 여기서도 수정이 필요한대요, "첫번째탭에들어갈내용이담긴액티비티이름"... 길긴한대 일단 가봅시다
이 부분도 수정이 필요합니다
그런대 지금은 필요가 없으니 일단 넘어가겠습니다
분홍색으로 칠해진 것은 추가가 필요합니다 ㅎㅎ
그다음 초록색으로 칠해져 있는 return 3; 은 탭의 갯수를 반환합니다
이미 눈치채신분들은 아시겠지만 탭의 갯수를 줄이려면 이 값을 줄인다음 switch-case문도 줄여주면 되겠지요??
DummySectionFragment로 탭을 구현할 수도 있지만 onCreateView() 메소드는 inflater 객체를 사용하여 뷰를
반환하여 화면에 뿌려주므로 getItem() 메소드로 탭 화면을 지정할 때에 비해 코드가 길어지므로 지워버립니다
마지막 파란색 부분은 탭의 이름입니다
return getString(R.string.title_section1).toUpperCase(l);
굵고 밑줄친 부분이 탭의 이름이 되는대요 이부분은 어떻게 이루어져 있냐,
R(R.java파일을 참조합니다).string(R파일중 string부분을 참조합니다, 즉 values/string.xml을 참조합니다)
.title_section1(title_section1이란 이름의 값을 반환합니다)
이렇게 생각하시면됩니다 저도 이렇게 생각했고요
(이글이 올려지는 당시가 강좌가 하나도 올라와 있지 않지만 시간이 지나 강좌를 많이 쓴다음 차례가 되면 넣을탠대
그때쯤이면 더 쉽게 이해가 되실겁니다 지금은 이해하지 않아도 됩니다)
그럼 탭의 이름을 수정하기 위해서는 values/string.xml을 수정해야 겠죠?
이부분은 너무 쉬우니 따로 말씀드리지는 않겠습니다
밑줄이 그어 있는 onCreateOptionsMenu 메소드는 메뉴키를 누르면 뜨는 내용을 정의하는건대 필요없으니 삭제합니다
이제 MainActivity는 끝났습니다
이어서 각 탭에 들어갈 내용물들을 만들어 봅시다
만들고 있던 프로젝트에 마우스 오른쪽을 누른다음 New-other-Android Activity를 눌러주세요
아무렇게나 BlankActivity를 만들어 주신다음 소스를 확인해 봅시다
package com.tistory.whdghks913.exampletabs;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
public class Tabs1 extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabs1);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.tabs1, menu);
return true;
}
}
너무 간단합니다 ㅎㅎ...;
각 탭에 나타날 화면과 관련된 모든 자바 소스를 이곳에 기록해야 합니다
자 아래와 같이 그냥 수정해 주세요
package com.tistory.whdghks913.exampletabs;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@SuppressLint("ValidFragment")
public class Tabs1 extends Fragment {
Context mContext;
public Tabs1(Context context) {
mContext = context;
}
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_tabs1, null);
return view;
}
}
위 원본소스의 취소선은 삭제된 부분, 아래 소스의 굵은 부분은 추가, 수정된 부분 입니다
밑줄친 부분은 다들 아시다 싶이 레이아웃을 결정하는 xml에 관한 구문입니다
MainActivity는 FragmentActivity를 상속하지만 탭에 들어갈 내용들은 Fragment을 상속(extends)해야 합니다
혹시 Fragment에 대해 더 알고 싶으시다면
http://developer.android.com/guide/components/fragments.html
http://developer.android.com/reference/android/support/v4/app/FragmentActivity.html
이제 이런 소스와 같이 나머지 탭에 들어갈 내용물들도 하나씩 구성해 주시면 됩니다
모든 탭의 구성이 끝났다면 아까 MainActivity에서 건너뛰었던 부분으로 돌아가 이름을 지정해야하는대요
switch(position) {
case 0:
return new 첫번째탭에들어갈내용이담긴액티비티이름(mContext);
case 1:
return new 두번째탭에들어갈내용이담긴액티비티이름(mContext);
case 2:
return new 세번째탭에들어갈내용이담긴액티비티이름(mContext);
}
위 세개의 문구를 만드신 Activity의 이름으로 변경해 주시면 됩니다
이제 빌드 해보시고 작동 시켜 보시면 각 탭과 연결된 xml에 기록된 내용물들이 탭 아래에 나타나는것을 볼수 있습니다
자 근대 문제가 발생했습니다
우리가 탭을 구현하기 위해 쓴것은 Fragment, 그런대 Fragment에서는 findViewById가 잘 작동하지 않는대요
Button button1;
button1 = (Button) view.findViewById(R.id.button1);
이렇게 구현하시면 쉽게 작동됩니다 ㅎㅎ
위치는 View view = inflater.inflate(R.layout.activity_tab1, null);와 return view;사이에 넣어주세요
실행 스샷
옆으로 스크롤하면 나타납니다
메뉴 아이탬을 아래로 이동하는것은 가능합니다
일명 루익처럼 말이죠
이렇게 아래로 이동하는것은 가능하며, API 14 (4.0)이상에서 사용가능합니다
<activity .. android:uiOptions="splitActionBarWhenNarrow" ..></activity>
이 빨간 문구를 AndroidManifest.xml의 <activity> 부분에 넣어주세요
API 14보다 낮을경우, 이 구문은 무시됩니다
예제소스
=======================
=======================
=======================
출처:http://muzesong.tistory.com/84
한 화면을 여러 공간으로 쪼개어 사용하거나 액티비티 이동없이 화면 내부구성을 다른 레이아웃으로
교체 시킬 때 등 Fragment는 여러 군데에서 사용되어지고 있습니다.
Fragment 란 ? : http://androidhuman.tistory.com/469
Fragment를 사용하려면 그것을 사용하는 상위 activity가 FragmentActivity 여야 합니다.
Fragment 생명주기는 activity와 흡사하며 주의 할 점이 activity에서 this로 쓰던 부분을 getActivity()로
바꿔 써주셔야 합니다.
큰 구성은 FragmentActivity를 상속받은 MainActivity.java 가 있고 Fragment 를 상속받은
OneFragment, TwoFragment, ThreeFragment.java 세가지 클래스를 만든다음
activity_main.xml에 있는 ll_fragment 영역에 위에만든 세가지 fragment 를 삽입하는 방식입니다.
먼저 MainActivity 구성입니다.
위 그림과 같이 activity_main.xml 레이아웃 하나에 fragment 가 교체 될 영역과 그 영역을 컨트롤 할
메뉴 뷰 를 만들어 줍니다.
<MainActivity>
public class MainActivity extends FragmentActivity implements OnClickListener {
final String TAG = "MainActivity";
int mCurrentFragmentIndex;
public final static int FRAGMENT_ONE = 0;
public final static int FRAGMENT_TWO = 1;
public final static int FRAGMENT_THREE = 2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bt_oneFragment = (Button) findViewById(R.id.bt_oneFragment);
bt_oneFragment.setOnClickListener(this);
Button bt_twoFragment = (Button) findViewById(R.id.bt_twoFragment);
bt_twoFragment.setOnClickListener(this);
Button bt_threeFragment = (Button) findViewById(R.id.bt_threeFragment);
bt_threeFragment.setOnClickListener(this);
mCurrentFragmentIndex = FRAGMENT_ONE;
fragmentReplace(mCurrentFragmentIndex);
}
public void fragmentReplace(int reqNewFragmentIndex) {
Fragment newFragment = null;
Log.d(TAG, "fragmentReplace " + reqNewFragmentIndex);
newFragment = getFragment(reqNewFragmentIndex);
// replace fragment
final FragmentTransaction transaction = getSupportFragmentManager()
.beginTransaction();
transaction.replace(R.id.ll_fragment, newFragment);
// Commit the transaction
transaction.commit();
}
private Fragment getFragment(int idx) {
Fragment newFragment = null;
switch (idx) {
case FRAGMENT_ONE:
newFragment = new OneFragment();
break;
case FRAGMENT_TWO:
newFragment = new TwoFragment();
break;
case FRAGMENT_THREE:
newFragment = new ThreeFragment();
break;
default:
Log.d(TAG, "Unhandle case");
break;
}
return newFragment;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_oneFragment:
mCurrentFragmentIndex = FRAGMENT_ONE;
fragmentReplace(mCurrentFragmentIndex);
break;
case R.id.bt_twoFragment:
mCurrentFragmentIndex = FRAGMENT_TWO;
fragmentReplace(mCurrentFragmentIndex);
break;
case R.id.bt_threeFragment:
mCurrentFragmentIndex = FRAGMENT_THREE;
fragmentReplace(mCurrentFragmentIndex);
break;
}
}
}
전체적으로 보면 fragment 마다 int으로된 구분자를 주고 메뉴 버튼이 클릭 될 때마다 해당 fragment의
index를 mCurrentFragmentIndex 라는 int 형 변수에 담아 fragment 교체 매소드를 태우는 식입니다.
onCreate부터 보면 메뉴 버튼등록과 리스너를 달고 mCurrentFragmentIndex에 첫 화면 fragment인
FRAGMENT_ONE 를 넣어주고 fragmentReplace 매소드를 타게됩니다.
fragmentReplace 매소드에는 넘겨받은 fragment index를 가지고 getFragment 매소드를 가서
실질적인 fragment의 객체 생성을 하고 그 객체를 리턴해줍니다.
다시 fragmentReplace매소드로 돌아와 리턴받은 fragment로 ll_fragment 라는 레이아웃 영역에
교체를 하게 됩니다. 다른 버튼을 눌렀을 때도 이와 같은 방식으로 동작하게 됩니다.
Fragment 들은
public class OneFragment extends Fragment implements OnClickListener {
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.onefragment, container, false);
Button button = (Button) v.findViewById(R.id.bt_ok);
button.setOnClickListener(this);
return v;
}
@Override public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_ok:
Toast.makeText(getActivity(), "OneFragment", Toast.LENGTH_SHORT).show();
break;
}
}
}
이처럼 Activity와 비슷한 구조이고
마지막으로 activity_main.xml 구조입니다.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffffff"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/ll_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:background="#ffffffff"
android:orientation="horizontal" >
<Button
android:id="@+id/bt_oneFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="1" />
<Button
android:id="@+id/bt_twoFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="2" />
<Button
android:id="@+id/bt_threeFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="3" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
ll_fragment 라는 영역이 Fragment들이 교체 될 영역입니다.
=======================
=======================
=======================
출처: 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
<?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
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
<?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
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
<?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
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
<?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
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
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 에 추가
<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의 형태는 아래와 같습니다.
- 좌측은 메뉴 형태로 각 사이트로 이동할 수 있는 버튼이 4개 있습니다.
- 버튼을 클릭하면 우측 Webview가 해당 사이트로 이동합니다.
- 처음 시작은 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
=======================
=======================
=======================
'스마트기기개발관련 > 안드로이드 개발' 카테고리의 다른 글
안드로이드 Dialog창에 테두리 없애기, 투명도 주기,배경투명도, 꾸미기 관련 (AlertDialog, popup, Dialog 등등 (0) | 2020.09.18 |
---|---|
안드로이드 개발 portrait & landscape 처리, 화면 회전 관련 (0) | 2020.09.18 |
안드로이드 동영상 재생 관련 (0) | 2020.09.18 |
안드로이드 타이머 구현 관련 (0) | 2020.09.18 |
안드로이드 디바이스 정보 알아내기 관련 (0) | 2020.09.18 |