各位Android安卓開發者大家好,小黑人這次很快的向大家分享新文章啦!
這篇文章要與大家分享的是"客製化滑動選單",簡單來說就像是抽屜的上升下降效果,那為什麼要用這種滑動選單的效果呢?答案就是要節省手機的畫面空間,例如一些功能選項可以先在畫面藏起來,等需要用到時再展現出來就好,那要怎麼客製滑動選單呢?就讓我們繼續往下看吧~
1. 首先,要客製滑動選單其實很容易,只要在Activity(.java)裡做上下滑動控制就好,再來比較要注意的一點是滑動距離的控制,因為Android的裝置手機有很多解析度,所以每個手機長寬也都不一樣,所以我們在滑動的距離還要另外針對不同解析度來進行判斷,小黑人這個範例是使用全螢幕的狀態下撰寫,所以大家先在AndroidManifest.xml上加入android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen",這樣才會有全螢幕的效果,然後也把Activity鎖定一個方向吧。
例如 :
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
>
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
2. 再來就是Layout(.xml)的設定,大家可以自己設計選單的排列方式,小黑人先以一個LinearLayout當作選單來向大家說明。
例如 :
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background"
>
<LinearLayout
android:id="@+id/menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/menu"
android:orientation="horizontal"
/>
</RelativeLayout>
3. 最後就是重點的地方了,也就是Activity(.java)的控制動作,大家可以看下方完整程式碼。
public class MainActivity extends Activity
{
//可滑動的Menu選單
private LinearLayout mMenu;
//Menu的版面控制元件
private RelativeLayout.LayoutParams mLayoutParams;
//配合多解析度畫面,會調整Menu的高度
private int HEIGHT;
//讀取手機裝置資訊元件
private DisplayMetrics mPhone;
//判斷Menu展開或關閉狀態
private Boolean mState = false;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//獲取手機裝置資訊
mPhone = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(mPhone);
//Menu的高度
HEIGHT = (int) (((float) mPhone.heightPixels / (float) 1280) * (float) 154) ;
//Menu版面控制的初始設定
mLayoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,HEIGHT);
//將Menu位置調整至底部
mLayoutParams.topMargin = (mPhone.heightPixels - HEIGHT);
//Menu元件
mMenu = (LinearLayout) findViewById(R.id.menu);
//將設定帶入
mMenu.setLayoutParams(mLayoutParams);
//點擊Menu觸發
mMenu.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
//判斷Menu狀態,是展開狀態還是閉合狀態
if(mState)
{
//Menu上升
new MoveTask().execute(false);
mState = false;
}
else
{
//Menu下降
new MoveTask().execute(true);
mState = true;
}
}
});
}
//Menu滑動類別
private class MoveTask extends AsyncTask<Boolean, Integer, Boolean>
{
@Override
protected Boolean doInBackground(Boolean... params)
{
//上升或下降動作判斷
if(params[0])
{
//滑動動作分成10個階段
for(int i = 1 ; i < 11 ; i++)
{
//動作切換
publishProgress(i);
//停0.05秒後繼續動作
try { Thread.sleep(50);} catch (InterruptedException e) {}
}
}
else
{
//滑動動作分成10個階段
for(int i = 10 ; i > -1 ; i--)
{
//動作切換
publishProgress(i);
//停0.05秒後繼續動作
try { Thread.sleep(50);} catch (InterruptedException e) {}
}
}
return true;
}
@Override
protected void onProgressUpdate(Integer... values)
{
//Menu每個階段位置
int y = values[0] * (((HEIGHT/4)*3)/10);
//將Menu每個位置帶入
mLayoutParams.topMargin = (mPhone.heightPixels - HEIGHT) + y;
mLayoutParams.bottomMargin = -y;
//將設定放入Menu裡
mMenu.setLayoutParams(mLayoutParams);
}
}
}
這整段程式裡包含手機解析度讀取、滑動距離換算、選單上下滑動控制,整體看來還不會很複雜,小黑人這個範例分享主要是強調滑動效果的運作,如果還要更多控制的話,大家可以再繼續加入判斷,讓滑動選單的功能更多更流暢。
最後,小黑人範例實作的擷圖畫面如下 :
例如 :
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
>
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
2. 再來就是Layout(.xml)的設定,大家可以自己設計選單的排列方式,小黑人先以一個LinearLayout當作選單來向大家說明。
例如 :
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background"
>
<LinearLayout
android:id="@+id/menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/menu"
android:orientation="horizontal"
/>
</RelativeLayout>
3. 最後就是重點的地方了,也就是Activity(.java)的控制動作,大家可以看下方完整程式碼。
public class MainActivity extends Activity
{
//可滑動的Menu選單
private LinearLayout mMenu;
//Menu的版面控制元件
private RelativeLayout.LayoutParams mLayoutParams;
//配合多解析度畫面,會調整Menu的高度
private int HEIGHT;
//讀取手機裝置資訊元件
private DisplayMetrics mPhone;
//判斷Menu展開或關閉狀態
private Boolean mState = false;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//獲取手機裝置資訊
mPhone = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(mPhone);
//Menu的高度
HEIGHT = (int) (((float) mPhone.heightPixels / (float) 1280) * (float) 154) ;
//Menu版面控制的初始設定
mLayoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,HEIGHT);
//將Menu位置調整至底部
mLayoutParams.topMargin = (mPhone.heightPixels - HEIGHT);
//Menu元件
mMenu = (LinearLayout) findViewById(R.id.menu);
//將設定帶入
mMenu.setLayoutParams(mLayoutParams);
//點擊Menu觸發
mMenu.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
//判斷Menu狀態,是展開狀態還是閉合狀態
if(mState)
{
//Menu上升
new MoveTask().execute(false);
mState = false;
}
else
{
//Menu下降
new MoveTask().execute(true);
mState = true;
}
}
});
}
//Menu滑動類別
private class MoveTask extends AsyncTask<Boolean, Integer, Boolean>
{
@Override
protected Boolean doInBackground(Boolean... params)
{
//上升或下降動作判斷
if(params[0])
{
//滑動動作分成10個階段
for(int i = 1 ; i < 11 ; i++)
{
//動作切換
publishProgress(i);
//停0.05秒後繼續動作
try { Thread.sleep(50);} catch (InterruptedException e) {}
}
}
else
{
//滑動動作分成10個階段
for(int i = 10 ; i > -1 ; i--)
{
//動作切換
publishProgress(i);
//停0.05秒後繼續動作
try { Thread.sleep(50);} catch (InterruptedException e) {}
}
}
return true;
}
@Override
protected void onProgressUpdate(Integer... values)
{
//Menu每個階段位置
int y = values[0] * (((HEIGHT/4)*3)/10);
//將Menu每個位置帶入
mLayoutParams.topMargin = (mPhone.heightPixels - HEIGHT) + y;
mLayoutParams.bottomMargin = -y;
//將設定放入Menu裡
mMenu.setLayoutParams(mLayoutParams);
}
}
}
這整段程式裡包含手機解析度讀取、滑動距離換算、選單上下滑動控制,整體看來還不會很複雜,小黑人這個範例分享主要是強調滑動效果的運作,如果還要更多控制的話,大家可以再繼續加入判斷,讓滑動選單的功能更多更流暢。
最後,小黑人範例實作的擷圖畫面如下 :
看似平凡的縮放抽屜效果,其實依不同需求與設計都會有不一樣的呈現方式,大家可以一起設計看看怎樣的滑動選單才是最貼切使用者的需求!
謝謝大家,如有任何問題都可以和小黑人一起交流討論!
☆小黑人☆
☆小黑人☆
請問像是晶鑽美甲這個app, 固定下方的選單, 但是icon可以無限增加延伸, 這種滑動的選單. 怎麼做? 要點是甚麼? 謝謝
回覆刪除