Android實戰_note1(MyMirror_一款小型攝像處理的App)
最近在實戰做明日科技的一個叫《魔鏡》的APP,接觸到不少有趣的技能tip,這裡記錄一下。功能點主要有啟動頁、攝像頭設定、亮度調節、相機焦距調節。介面選擇換鏡框、吹氣起霧、長安碎屏、搖一搖換鏡框、系統幫助等子功能,部落格會陸續更近
本文自覺有些有趣的地方(這裡僅做摘要,詳見文中):
- handler.sendEmptyMessageDelayed()
- 1.3 中的修改全域性配置檔案 AndroidManifest.xml
- name屬性表示顏色變數名,在java中呼叫時就是呼叫這個名稱;#3F51B5表示顏色值;呼叫格式為@color/setbackground。其中顏色值可以直接在xml中輸入,或者點選色塊,在彈出視窗中進行選擇或輸入設定;(如文《資源準備1:顏色資源》中圖)
- 資源準備4:styles樣式資源
MyTheme表示樣式的名稱,
android:windowFrame表示視窗的背景顏色,
android:windowBackground表示視窗的背景圖片,
android:windowIsTranslucent表示視窗是否顯示,
android:windowNoTitle表示視窗是否有標題 - 一般情況,除了直接使用放在drawable目錄下的圖片,其實drawable的用法都與XML有關,使用shape、layer-list等標籤繪製一些背景,還可以通過selector標籤定義view的狀態效果。
功能點1.快速構建啟動頁:
此時目錄結構:
1.1 Activity.java全文:
注意程式碼中的註釋,其中 handler.sendEmptyMessageDelayed(1,3000); 這個方法比較有趣
package com.example.mymirror.activity; import android.content.Intent; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.KeyEvent; import com.example.mymirror.MainActivity; import com.example.mymirror.R; public class GuideActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_guide); handler.sendEmptyMessageDelayed(1,3000);//傳遞what值為1的,空訊息,延遲3秒 } //訊息處理,接收訊息 private Handler handler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message msg) { if (msg.what == 1){ //建立意圖 Intent intent = new Intent(GuideActivity.this, MainActivity.class); startActivity(intent);//跳轉介面 finish();//關閉介面 } return false; } }); //遮蔽返回鍵 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK){ return false; } return false; } }
1.2 佈局問價設定背景圖片:
android:background="@mipmap/background"
全文:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/background"
tools:context="com.example.mymirror.activity.GuideActivity">
</android.support.constraint.ConstraintLayout>
1.3 修改全域性配置檔案 AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mymirror">
<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/Theme.AppCompat.Light.NoActionBar">
<activity android:name=".activity.GuideActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity"></activity>
</application>
</manifest>
到此,執行程式,結果:啟動頁介面停頓3秒後,切到MainActivity上:
停頓3秒後,切到MainActivity上
2.主窗體模組設計
資源準備1:顏色資源
開啟app/res/values目錄下的colors.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="setbackground">#a6000000</color>
<color name="white">#FFFFFF</color>
<color name="setbackground2">#3FFFFFFF</color>
<color name="setbackground3">#00000000</color>
<color name="setbackground4">#7e000000</color>
</resources>
name屬性表示顏色變數名,在java中呼叫時就是呼叫這個名稱;#3F51B5表示顏色值;呼叫格式為@color/setbackground。其中顏色值可以直接在xml中輸入,或者點選下圖框中的色塊,在彈出視窗中進行選擇或輸入設定:
資源準備2:尺寸資源
呼叫格式為@dimen/dp_0
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--尺寸資源 -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="dp_0">0dp</dimen>
<dimen name="dp_3">3dp</dimen>
<dimen name="dp_5">5dp</dimen>
<dimen name="dp_10">10dp</dimen>
<dimen name="dp_18">18dp</dimen>
<dimen name="dp_20">20dp</dimen>
<dimen name="dp_30">30dp</dimen>
<dimen name="dp_45">45dp</dimen>
<dimen name="dp_55">55dp</dimen>
<dimen name="dp_160">160dp</dimen>
<dimen name="dp_200">200dp</dimen>
<dimen name="dp_300">300dp</dimen>
</resources>
資源準備3:字串資源
<resources>
<string name="app_name">MyMirror</string>
<string name="back_txt">返回</string>
</resources>
資源準備4:styles樣式資源
MyTheme表示樣式的名稱,
android:windowFrame表示視窗的背景顏色,
android:windowBackground表示視窗的背景圖片,
android:windowIsTranslucent表示視窗是否顯示,
android:windowNoTitle表示視窗是否有標題
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="MyTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowFrame">@android:color/transparent</item>
<item name="android:windowBackground">@color/setbackground4</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowNoTitle">true</item>
</style>
</resources>
資源準備5:drawable圖片資源
一般情況,除了直接使用放在drawable目錄下的圖片,其實drawable的用法都與XML有關,使用shape、layer-list等標籤繪製一些背景,還可以通過selector標籤定義view的狀態效果。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false" android:drawable="@drawable/back_shape_pink"/>
<item android:state_pressed="true" android:drawable="@drawable/back_shape_white"/>
</selector>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!--實心 -->
<solid android:color="@color/setbackground2"/>
<!--描邊 -->
<stroke android:color="@color/white"
android:width="@dimen/dp_3"/>
<!--圓角 -->
<corners android:radius="@dimen/dp_20"/>
<!--間隔 -->
<padding android:left="@dimen/dp_10"
android:top="@dimen/dp_5"
android:bottom="@dimen/dp_5"
android:right="@dimen/dp_10"/>
</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/setbackground2"/>
<stroke android:color="@color/colorAccent"
android:width="@dimen/dp_3"/>
<corners android:radius="@dimen/dp_20"/>
<padding android:left="@dimen/dp_10"
android:top="@dimen/dp_5"
android:bottom="@dimen/dp_5"
android:right="@dimen/dp_10"/>
</shape>
資源準備6:mipmap資源(專案完成後附上碼雲地址)
主窗體佈局:
即activity_main.xml佈局,佈局設計框架如下:
<!--SurfaceView控制元件,主介面最底層的顯示區域,用來顯示攝像頭的內容-->
<!--PictureView:自定義控制元件,在此控制元件上完成鏡框更換的功能,佈滿整個顯示區域-->
<!--FunctionView:自定義控制元件,功能組合控制元件,將系統幫助、選擇相框和亮度調節等3個功能組合到一起,形成主介面頂部功能區-->
<!--LinearLayout佈局:底部焦距調節功能-->
<!--縮小焦距按鈕-->
<!--拖動條控制元件-->
<!--放大焦距按鈕-->
<!--DrawView:吹霧擦霧圖層-->
activity_main.xml全文:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.MainActivity">
<!--此處新增主介面上的佈局元件 -->
<SurfaceView
android:id="@+id/surface"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<com.example.mymirror.view.PictureView
android:id="@+id/picture"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"/>
<com.example.mymirror.view.FunctionView
android:id="@+id/function"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:id="@+id/bottom_bar"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:padding="@dimen/dp_10">
<!-- 放大、縮小按鈕和拖動條佈局程式碼-->
<ImageView
android:id="@+id/minus"
android:layout_marginLeft="@dimen/dp_30"
android:layout_width="@dimen/dp_45"
android:layout_height="@dimen/dp_45"
android:src="@mipmap/downsmall"
android:scaleType="centerInside"/>
<SeekBar
android:id="@+id/seekbar"
android:layout_width="@dimen/dp_0"
android:layout_height="wrap_content"
android:layout_weight="1"
android:progress="0"
android:thumbOffset="@dimen/dp_0"/>
<ImageView
android:id="@+id/add"
android:layout_marginRight="@dimen/dp_30"
android:layout_width="@dimen/dp_45"
android:layout_height="@dimen/dp_45"
android:src="@mipmap/uplarge"
android:scaleType="centerInside"/>
</LinearLayout>
<com.example.mymirror.view.DrawView
android:id="@+id/draw_glasses"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"/>
</RelativeLayout>
Design介面顯示:
建立view包,在包中新增PictureView、FunctionView、DrawView三個java檔案用於描述自定義控制元件:
layout資料夾下建立檔案view_function.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="wrap_content"
android:padding="@dimen/dp_10"
android:background="@color/setbackground"
android:gravity="center">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="@dimen/dp_30">
<!-- 問號 按鈕-->
<ImageView
android:id="@+id/hint"
android:layout_centerVertical="true"
android:layout_width="@dimen/dp_45"
android:layout_height="@dimen/dp_45"
android:scaleType="centerInside"
android:src="@mipmap/hint"/>
<!-- 選擇相框 按鈕-->
<ImageView
android:id="@+id/choose"
android:layout_width="@dimen/dp_45"
android:layout_height="@dimen/dp_45"
android:layout_centerVertical="true"
android:src="@mipmap/choose"
android:scaleType="centerInside"
android:layout_alignParentRight="true"/>
<!-- 燈泡圖示-->
<ImageView
android:id="@+id/cencer"
android:layout_width="@dimen/dp_45"
android:layout_height="@dimen/dp_45"
android:src="@mipmap/light"
android:scaleType="centerInside"
android:layout_centerInParent="true"/>
<!-- 減亮度 按鈕-->
<ImageView
android:id="@+id/light_down"
android:layout_width="@dimen/dp_45"
android:layout_height="@dimen/dp_45"
android:layout_centerVertical="true"
android:src="@mipmap/downlight"
android:scaleType="centerInside"
android:layout_toLeftOf="@+id/cencer"
android:layout_marginRight="@dimen/dp_20"/>
<!-- 加亮度 按鈕-->
<ImageView
android:id="@+id/light_up"
android:layout_width="@dimen/dp_45"
android:layout_height="@dimen/dp_45"
android:layout_centerVertical="true"
android:src="@mipmap/uplight"
android:scaleType="centerInside"
android:layout_toRightOf="@+id/cencer"
android:layout_marginLeft="@dimen/dp_20"/>
</RelativeLayout>
</LinearLayout>
對應預覽圖:
FunctionView全文:
package com.example.mymirror.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
/**
* Created by 700 on 2018/8/23.
*/
public class FunctionView extends LinearLayout implements View.OnClickListener{
private LayoutInflater mInflater;//宣告尋找XML檔案類
private ImageView hint,choose,down,up;//控制元件物件
/**
* 回撥介面,4個按鈕
*/
private onFunctionViewItemClickListener listener;
public interface onFunctionViewItemClickListener{
void hint();//提示
void choose();//選擇相框
void down();//減少亮度
void up();//增加亮度
}
/**
* 初始化建構函式
*/
public FunctionView(Context context) {
super(context);
}
public FunctionView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FunctionView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void onClick(View v) {
}
public void setOnFunctionViewItemClickListener(onFunctionViewItemClickListener monFunctionViewItemClickListener){
this.listener = monFunctionViewItemClickListener;//設定監聽物件
}
}
PictureView全文:
package com.example.mymirror.view;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ImageView;
/**
* Created by 700 on 2018/8/23.
*/
public class PictureView extends ImageView {
public PictureView(Context context) {
super(context);
}
public PictureView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public PictureView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
DrawView全文:
package com.example.mymirror.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by 700 on 2018/8/23.
*/
public class DrawView extends View{
public DrawView(Context context) {
super(context);
}
public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DrawView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
執行結果: