2017. 12. 6. 23:53ㆍAndroid
Guide Splash Activity with Viewpager
# GuideSplashActivity.java 생성 및 manifest 수정
SplashActivity가 제일 먼저 실행되고 이후에 '시작하기' 버튼을 누르면 MainActivity로 넘어가게 설정한다.
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"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.jaehyukshin.welcomeseoulloreview"> <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> </activity> <activity android:name=".GuideSplashActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> | cs |
# Guide화면으로 보여질 layout 파일을 추가함
애플리케이션의 기본적인 설명을 해줄 화면을 layout xml 파일로 나눠서 보여줄 예정
ViewPager로 xml Layout 파일을 넘겨가면서 앱 가이드를 볼 수 있게 만들 것임.
예제로 기본 layout 파일 3개를 추가했음.
guide_splash_activity1, guide_splash_activity2, guide_splash_activity3를 추가함
# colors.xml에 색깔 저장 및 dimens.xml에 크기 저장, arrays.xml에 배열 저장
colors.xml 및 dimens.xml, arrays.xml 파일 없으면 values에 리소스 파일 새로 생성하면 됨
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 | <?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#7BA293</color> <color name="colorPrimaryLight">#8BE3CE</color> <color name="colorPrimaryDark">#303F9F</color> <color name="colorAccent">#FD8BB1</color> <color name="greenNike">#7BA293</color> <color name="orangeGolfwang">#FDA293</color> <color name="pinkGolfwang">#EECEDF</color> <color name="colorPrimaryTranslucent">#CC7BA293</color> <color name="orangeGolfwangTranslucent">#CCFDA293</color> <!-- dots inactive colors --> <color name="dot_dark_screen1">@color/white</color> <color name="dot_dark_screen2">@color/white</color> <color name="dot_dark_screen3">@color/white</color> <color name="dot_dark_screen4">@color/white</color> <!-- dots active colors --> <color name="dot_light_screen1">@color/orangeGolfwang</color> <color name="dot_light_screen2">@color/orangeGolfwang</color> <color name="dot_light_screen3">@color/orangeGolfwang</color> <color name="dot_light_screen4">@color/orangeGolfwang</color> <color name="black">#000000</color> <color name="white">#FFFFFF</color> <color name="spaceGray">#c0c5ce</color> </resources> | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?xml version="1.0" encoding="utf-8"?> <resources> <dimen name="dots_height">30dp</dimen> <dimen name="dots_margin_bottom">20dp</dimen> <dimen name="img_width_height">120dp</dimen> <dimen name="padding_small">4dp</dimen> <dimen name="padding_medium">8dp</dimen> <dimen name="padding_large">16dp</dimen> <!-- Default screen margins, per the Android Design guidelines. --> <dimen name="activity_horizontal_margin">16dp</dimen> <dimen name="activity_vertical_margin">16dp</dimen> <dimen name="fab_margin">16dp</dimen> <dimen name="image_loader_post_width">450dp</dimen> </resources> | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?xml version="1.0" encoding="utf-8"?> <resources> <array name="array_dot_active"> <item>@color/dot_light_screen1</item> <item>@color/dot_light_screen2</item> <item>@color/dot_light_screen3</item> <item>@color/dot_light_screen4</item> </array> <array name="array_dot_inactive"> <item>@color/dot_dark_screen1</item> <item>@color/dot_dark_screen2</item> <item>@color/dot_dark_screen3</item> <item>@color/dot_dark_screen4</item> </array> </resources> | cs |
# GuideSplashActivity에 사용될 버튼 모양 drawable에 설정
splash_button_shape.xml 파일 drawable에 추가
가이드 스플래시 화면에서 사용할 버튼을 반투명한 색을 설정하기 위해 설정해놓은 colorPrimaryTranslucent라는 color를 사용함
colorPrimary 색 코드가 #7BA293 RGB 이라면, colorPrimaryTranslucent는 7BA293 앞에 투명도 값 CC(16진수 투명값 %)를 붙여서 투명도를 추가해주면 된다.
colorPrimaryTranslucent #CC7BA293 ARGB
CC 이외에도 투명 %퍼센티지마다의 값을 달리해서 넣어주면 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true"> <shape> <corners android:radius="5dp" /> <solid android:color="@color/colorPrimaryTranslucent" /> </shape> </item> <item> <shape> <corners android:radius="5dp" /> <solid android:color="@color/colorPrimaryTranslucent" /> </shape> </item> </selector> | cs |
# guide_splash_activity.xml button background 속성을 drawable에 설정한 splash_button_shape로 설정
1 2 3 4 5 6 7 8 9 10 11 | <Button android:id="@+id/btn_start" android:layout_width="300dp" android:layout_height="wrap_content" android:layout_gravity="center_horizontal|bottom" android:layout_marginBottom="50dp" android:background="@drawable/splash_button_shape" android:text="시작하기" android:textColor="@android:color/white" android:textStyle="bold" android:visibility="invisible"/> | cs |
# MyViewPagerAdapter 추가
GuideSplashActivity에서 사용하는 ViewPager를 따로 만들어서 사용
btnStart 버튼을 3개의 가이드 화면에서 마지막 세 번째 화면에만 등장하게 설정해둠
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 | ViewPager.OnPageChangeListener viewPagerPageChangeListener = new ViewPager.OnPageChangeListener() { @Override public void onPageSelected(int position) { addBottomDots(position); if (position == layouts.length - 1) { btnStart.setVisibility(View.VISIBLE); } else { btnStart.setVisibility(View.INVISIBLE); } } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageScrollStateChanged(int arg0) { } }; public class MyViewPagerAdapter extends PagerAdapter { private LayoutInflater layoutInflater; public MyViewPagerAdapter() { } @Override public Object instantiateItem(ViewGroup container, int position) { layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = layoutInflater.inflate(layouts[position], container, false); container.addView(view); return view; } @Override public int getCount() { return layouts.length; } @Override public boolean isViewFromObject(View view, Object obj) { return view == obj; } @Override public void destroyItem(ViewGroup container, int position, Object object) { View view = (View) object; container.removeView(view); } } | cs |
# 가이드 화면 중에서 몇 번째 화면인지 표시하는 Layout Dot 표시하기
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 | public class GuideSplashActivity extends Activity { private LinearLayout dotsLayout; private TextView[] dots; private int[] layouts; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); dotsLayout = (LinearLayout) findViewById(R.id.layoutDots); layouts = new int[]{ R.layout.guide_splash_slide1, R.layout.guide_splash_slide2, R.layout.guide_splash_slide3 }; // adding bottom dots addBottomDots(0); } private void addBottomDots(int currentPage) { dots = new TextView[layouts.length]; //해당화면 일때 int[] colorsActive = getResources().getIntArray(R.array.array_dot_active); //해당화면 아닐때 int[] colorsInactive = getResources().getIntArray(R.array.array_dot_inactive); dotsLayout.removeAllViews(); for (int i = 0; i < dots.length; i++) { //이부분 -1이라고 고침 dots[i] = new TextView(this); //HTML 코드를 가져와서 TextView text로 설정, •는 "•" 이거임 dot이 글자인 것임 dots[i].setText(Html.fromHtml("•")); //dot 크기 변경 dots[i].setTextSize(35); dots[i].setTextColor(colorsInactive[currentPage]); dotsLayout.addView(dots[i]); } if (dots.length > 0) dots[currentPage].setTextColor(colorsActive[currentPage]); } } | cs |
Guide 화면으로 사용할 layout 파일을 layouts 배열에 담아두고, 이 layout 갯수에 맞게 dot을 만들어서 표시함
Arrays에 추가한 선택된 layout dot 색 및 선택되지 않은 layout dot 색을 설정해줌
layout dot은 특별한 모양이 있는 것이 아니라, "•" 이 모양을 html 코드로 가져와서 안드로이드에서 표시한 것임.
따라서 특수 기호를 TextView로 나타냈고, 텍스트 크기만 바꾼 것임.
이렇게 생각하면 쉽게 LayoutDot을 만들 수 있다.
# 시작하기 버튼을 누르면 MainActivity 시작
1 2 3 4 | private void launchHomeScreen() { startActivity(new Intent(getApplicationContext(), MainActivity.class)); finish(); } | cs |
# Status bar 색 변경
버전 19는 상태바 색을 변경하는 것이 불가해서 버전 21 이상일 경우 상태바 색을 투명으로 변경해줌
1 2 3 4 5 6 7 8 9 | private void changeStatusBarColor() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Window window = getWindow(); window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); window.setStatusBarColor(Color.TRANSPARENT); getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); } } | cs |
# 뒤로가기 두 번 눌러야 종료
Toast가 띄워져 있는 상태에서 뒤로가기를 눌러야 앱이 종료되게 만드는 메소드 추가
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | private final long FINISH_INTERVAL_TIME = 2000; private long backPressedTime = 0; @Override public void onBackPressed() { long tempTime = System.currentTimeMillis(); long intervalTime = tempTime - backPressedTime; if (0 <= intervalTime && FINISH_INTERVAL_TIME >= intervalTime) { super.onBackPressed(); GuideSplashActivity.this.finish(); System.exit(0); } else { backPressedTime = tempTime; Toast.makeText(getApplicationContext(), "'뒤로' 버튼을 한 번 더 누르시면 종료됩니다.", Toast.LENGTH_SHORT).show(); } } | cs |
최종 코드
# GuideSplashActivity.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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | import android.app.Activity; import android.content.Context; import android.content.Intent; import android.graphics.Color; import android.os.Build; import android.os.Bundle; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.text.Html; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; public class GuideSplashActivity extends Activity { private final long FINISH_INTERVAL_TIME = 2000; private long backPressedTime = 0; private ViewPager viewPager; private MyViewPagerAdapter myViewPagerAdapter; private LinearLayout dotsLayout; private TextView[] dots; private int[] layouts; Button btnStart; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // making notification bar transparent changeStatusBarColor(); setContentView(R.layout.activity_guide_splash); viewPager = (ViewPager) findViewById(R.id.view_pager); dotsLayout = (LinearLayout) findViewById(R.id.layoutDots); btnStart = (Button) findViewById(R.id.btn_start); layouts = new int[]{ R.layout.guide_splash_slide1, R.layout.guide_splash_slide2, R.layout.guide_splash_slide3 }; // adding bottom dots addBottomDots(0); myViewPagerAdapter = new MyViewPagerAdapter(); viewPager.setAdapter(myViewPagerAdapter); viewPager.addOnPageChangeListener(viewPagerPageChangeListener); btnStart.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { launchHomeScreen(); } }); } private void changeStatusBarColor() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Window window = getWindow(); window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); window.setStatusBarColor(Color.TRANSPARENT); getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); } } private void launchHomeScreen() { startActivity(new Intent(getApplicationContext(), MainActivity.class)); finish(); } private void addBottomDots(int currentPage) { dots = new TextView[layouts.length]; //해당화면 일때 int[] colorsActive = getResources().getIntArray(R.array.array_dot_active); //해당화면 아닐때 int[] colorsInactive = getResources().getIntArray(R.array.array_dot_inactive); dotsLayout.removeAllViews(); for (int i = 0; i < dots.length; i++) { //이부분 -1이라고 고침 dots[i] = new TextView(this); dots[i].setText(Html.fromHtml("•")); dots[i].setTextSize(35); dots[i].setTextColor(colorsInactive[currentPage]); dotsLayout.addView(dots[i]); } if (dots.length > 0) dots[currentPage].setTextColor(colorsActive[currentPage]); } private int getItem(int i) { return viewPager.getCurrentItem() + i; } // viewpager change listener ViewPager.OnPageChangeListener viewPagerPageChangeListener = new ViewPager.OnPageChangeListener() { @Override public void onPageSelected(int position) { addBottomDots(position); if (position == layouts.length - 1) { btnStart.setVisibility(View.VISIBLE); } else { btnStart.setVisibility(View.INVISIBLE); } } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageScrollStateChanged(int arg0) { } }; public class MyViewPagerAdapter extends PagerAdapter { private LayoutInflater layoutInflater; public MyViewPagerAdapter() { } @Override public Object instantiateItem(ViewGroup container, int position) { layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = layoutInflater.inflate(layouts[position], container, false); container.addView(view); return view; } @Override public int getCount() { return layouts.length; } @Override public boolean isViewFromObject(View view, Object obj) { return view == obj; } @Override public void destroyItem(ViewGroup container, int position, Object object) { View view = (View) object; container.removeView(view); } } @Override public void onBackPressed() { long tempTime = System.currentTimeMillis(); long intervalTime = tempTime - backPressedTime; if (0 <= intervalTime && FINISH_INTERVAL_TIME >= intervalTime) { super.onBackPressed(); GuideSplashActivity.this.finish(); System.exit(0); } else { backPressedTime = tempTime; Toast.makeText(getApplicationContext(), "'뒤로' 버튼을 한 번 더 누르시면 종료됩니다.", Toast.LENGTH_SHORT).show(); } } } | cs |
# activity_guide_splash.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 41 42 43 44 45 46 | <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentTop="true" android:layout_alignParentStart="true"> <android.support.v4.view.ViewPager android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_alignParentTop="true" /> <LinearLayout android:id="@+id/layoutDots" android:layout_width="match_parent" android:layout_height="@dimen/dots_height" android:gravity="center" android:layout_gravity="center_horizontal|bottom" android:orientation="horizontal" android:layout_marginBottom="120dp"> </LinearLayout> <Button android:id="@+id/btn_start" android:layout_width="300dp" android:layout_height="wrap_content" android:layout_gravity="center_horizontal|bottom" android:layout_marginBottom="50dp" android:background="@drawable/splash_button_shape" android:text="시작하기" android:textColor="@android:color/white" android:textStyle="bold" android:visibility="invisible"/> </FrameLayout> </RelativeLayout> | cs |
# 샘플 영상
'Android' 카테고리의 다른 글
[서울시 앱 공모전 / 서울시를 이겨라] Tmap API 지도 띄우기 (1) | 2017.12.12 |
---|---|
[서울시 앱 공모전 / 서울시를 이겨라] Guide Splash Activity with VideoView (0) | 2017.12.08 |
[Global SW 공모대전] README 이미지 (0) | 2017.12.04 |
[서울시 앱 공모전 / 서울시를 이겨라] ViewPager with fragments (0) | 2017.11.24 |
[서울시 앱 공모전 / 서울시를 이겨라] 서울 열린데이터 광장 Open API 사용 / AsyncTask / Parsing (0) | 2017.11.22 |