由于原理一樣,so 就寫了仿鬥魚demo,左圖為demo,右圖為鬥魚平台的登入界面
寫這篇文章時,順便吐槽一下美團滿減活動越來越坑了,從滿25減4到滿30減2,周末夥食也不敢點貴的了。不過還是每天習慣性的點開看看今天抽到的滿減多少。
從我研究的幾個App中來看,就蘇甯的是直接使用View 覆寫在目前的頁面上面,其他都是另外開啟一個Activity,我想這樣的目的是為了不讓使用者可以點到背後的内容,邏輯也更清晰。這裡就隻講Activity形式的實作。
一、簡介及結論
一般在剛進美團app時,出現下面彈窗:
看到沒有!!!,雖然截圖沒截全,很明顯是滿34 減 4的通用紅包!!!默默下樓吃饅頭
通過Hierarchy View 工具可以看出 這個彈窗分為3個部分
1. com.facebook.drawee.view.SimpleDraweeView 其本質是ImageView,第三方庫,用來通過Uri進行加載圖檔
2. ListView //顯示具體内容
3. Button //用來進入主界面,直接finish本Activity
再看看這布局在哪個頁面中:
可以看到,該頁面為MainActivity ,那麼為啥有2個MainActivity呢?
其實彈窗是由下面那MainActivity 通過Intent 傳入彈出資訊,再開啟第二個MainActivity,第二個則通過Intent判斷,如果判斷為彈窗則加載彈窗的布局檔案。
結論:那麼從上面的講述之中,我們可以發現,該彈窗其實就是一個背景為透明的Activity。
再看看其他應用的一些場景,比如網易郵箱的更新、美團的更新、鬥魚的登入
這幾個例子,都和美團那個一樣,使用開啟Activity的方式彈窗,那麼下面來用demo,實作類似的效果。
二、demo解析
這邊講解2種方式,一種為啟動另一個activity,一種為啟動自身重新加載布局( 這種設定透明主題特别坑)
1. 啟動另一個activity
步驟: (1) 給button設定點選事件,開啟AdvertDialogActivity (2)給該Activity 進行配置透明主題,以及不需要其他的一些動畫效果 (3) 各個按鈕都有監聽事件,進行下一步的處理(本demo沒加上)
MainActivity:
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.click:
Intent intent = new Intent(this, AdvertDialogActivity.class);
startActivity(intent);
break;
AdvertDialogActivity.java
package com.example.stormxz.vasdialog;
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.View;
import android.widget.ImageView;
/**
* Created by stormxz on 2017/9/15.
*/
public class AdvertDialogActivity extends Activity implements View.OnClickListener{
private ImageView advert_close = null;
private ImageView advert_img = null;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login_dialog);
// initData(); //需要加載的圖檔 處理
initView(); //初始化view
// memoryThis(); //記錄下是否打開過 , 一般打開一次
}
private void initView() {
}
@Override
public void onClick(View view) {
int viewId = view.getId();
switch (viewId) {
}
}
@Override
public void finish()
{
super.finish();
overridePendingTransition(0, 0); //沒有效果的退出
}
}
設定該Activity 主題:
<!-- 彈窗 -->
<activity
android:name=".AdvertDialogActivity"
android:configChanges="fontScale|orientation|keyboardHidden|screenSize|smallestScreenSize|layoutDirection|screenLayout" //旋轉螢幕相關
android:exported="false" //不能為外部調用
android:launchMode="singleTop" //必須在棧頂
android:theme="@style/AdvertDialogActivity.Theme.NoTitleBar"> //設定主題
</activity>
<!-- 彈窗頁面樣式 -->
<style name="AdvertDialogActivity.Theme.NoTitleBar" parent="android:Theme.Translucent.NoTitleBar"> //系統的透明主題
<item name="android:windowAnimationStyle">@style/Animation</item> //取消Activity的一些動畫,比如進入,退出等
</style>
<style name="Animation">
<item name="android:activityOpenEnterAnimation">@null</item>
<item name="android:activityOpenExitAnimation">@null</item>
<item name="android:activityCloseEnterAnimation">@null</item>
<item name="android:activityCloseExitAnimation">@null</item>
<item name="android:taskOpenEnterAnimation">@null</item>
<item name="android:taskOpenExitAnimation">@null</item>
<item name="android:taskCloseEnterAnimation">@null</item>
<item name="android:taskCloseExitAnimation">@null</item>
<item name="android:taskToFrontEnterAnimation">@null</item>
<item name="android:taskToFrontExitAnimation">@null</item>
<item name="android:taskToBackEnterAnimation">@null</item>
<item name="android:taskToBackExitAnimation">@null</item>
</style>
2. 啟動自身activity
思路:通過Intent 傳遞參數,判斷加載的布局
MainActivity.java
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.click:
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("isUpdate", true);
startActivity(intent);
break;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (isUpdate) {
setContentView(R.layout.login_dialog); //類似鬥魚登入界面的布局
} else {
setContentView(R.layout.activity_main); //帶有button的布局
initView();
}
}
難點,給MainActivity添加透明主題
一般這個時候會想到使用動态設定主題,調用setTheme(主題id),此操作沒毛病啊,但是實際運作過程中,設定透明主題(和第一個例子一樣的主題)并沒有效果。
樓主試過将setTheme的位置放在setContentView之前也是無效的。
這時,解決方法如下:
在MainActivity中重寫方法setTheme()
//設定透明主題
@Override
public void setTheme(@StyleRes int resid) {
Intent intent = getIntent();
isUpdate = intent.getBooleanExtra("isUpdate", false);
if (isUpdate) {
super.setTheme(R.style.AdvertDialogActivity_Theme_NoTitleBar); //透明主題
} else {
super.setTheme(R.style.AppTheme); //普通主題
}
}
光這樣還是不夠的, 必須在AndroidManifest.xml中給MainActivity設定透明主題才有效果,如下設定:
<activity android:name=".MainActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar" //加其他主題是沒有效果的,親測
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
至此,透明主題設定完畢,接下來就是寫布局了
登入界面布局:
<?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="#BF000000"
android:orientation="vertical"
>
<LinearLayout
android:layout_gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_marginTop="80dp"
android:layout_marginBottom="80dp"
android:background="@drawable/bacgr">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_horizontal"
android:layout_marginTop="20dp"
>
<TextView
android:layout_width="40dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textSize="0.5dp"
android:background="#CDC5BF"/>
<TextView
android:text="選擇登入方式"
android:textColor="#CDC5BF"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_width="40dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textSize="0.5dp"
android:background="#CDC5BF"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginTop="20dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:background="@drawable/weixin"
android:gravity="center"
android:clickable="true">
<TextView
android:text="微信登入"
android:shadowRadius="5"
android:textColor="#00FF00"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginTop="10dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:background="@drawable/qq"
android:gravity="center"
android:clickable="true">
<TextView
android:text="QQ登入"
android:shadowRadius="5"
android:textColor="#00BFFF"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginTop="10dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:background="@drawable/weibo"
android:gravity="center"
android:clickable="true">
<TextView
android:text="微網誌登入"
android:shadowRadius="5"
android:textColor="#FF0000"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
>
<TextView
android:text="or"
android:textSize="15sp"
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginTop="10dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:background="@drawable/douyu"
android:gravity="center"
android:clickable="true">
<TextView
android:text="鬥魚賬号登入"
android:shadowRadius="5"
android:textColor="#FFFFFF"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
>
<TextView
android:text="快速注冊"
android:textColor="#EE7600"
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_gravity="center_horizontal">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">
<TextView
android:text="* 使用即為同意"
android:textSize="8sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:text="《鬥魚注冊協定及版權聲明》"
android:textSize="8sp"
android:textColor="#EE7600"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</FrameLayout>
</LinearLayout>
</LinearLayout>
圓角布局,這邊就給微信的圓角,其他一樣,重寫改下顔色,圓角角度即可
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFF" />
<corners android:topLeftRadius="10dp"
android:topRightRadius="10dp"
android:bottomRightRadius="10dp"
android:bottomLeftRadius="10dp"/>
<stroke android:width="1dp" android:color="#7CFC00" />
</shape>