編輯:關於Android編程


//采用的是聯動,使用Fragment管理器FragmentTransaction去實現fragment管理
package com.fuzhucheng.circlemenu;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private UpCircleMenuLayout myCircleMenuLayout;
//四個fragment頁面
private HomepageFragment homepageFragment;
private SettingFragment settingFragment;
private HistoryFragment historyFragment;
private FourthFragment fourthFragment;
private FifthFragment fifthFragment;
private String[] mItemTexts = new String[]{"安全中心 ", "特色服務", "投資理財",
"轉賬匯款", "我的賬戶", "安全中心", "特色服務", "投資理財", "轉賬匯款", "我的賬戶"};
private int[] mItemImgs = new int[]{R.drawable.home_mbank_1_normal,
R.drawable.home_mbank_2_normal, R.drawable.home_mbank_3_normal,
R.drawable.home_mbank_4_normal, R.drawable.home_mbank_5_normal,
R.drawable.home_mbank_1_normal, R.drawable.home_mbank_2_normal,
R.drawable.home_mbank_3_normal, R.drawable.home_mbank_4_normal,
R.drawable.home_mbank_5_normal};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//第一次初始化首頁默認顯示第一個fragment
initFragment1();
myCircleMenuLayout = (UpCircleMenuLayout) findViewById(R.id.id_mymenulayout);
myCircleMenuLayout.setMenuItemIconsAndTexts(mItemImgs);//一句設置圖片
myCircleMenuLayout.setOnMenuItemClickListener(new UpCircleMenuLayout.OnMenuItemClickListener() {
@Override
public void itemClick(int pos) {
Toast.makeText(MainActivity.this, mItemTexts[pos],
Toast.LENGTH_SHORT).show();
switch (pos) {
case 0:
initFragment1();
setTitle("安全中心");
break;
case 1:
initFragment2();
setTitle("特色服務");
break;
case 2:
initFragment3();
setTitle("投資理財");
break;
case 3:
initFragment4();
setTitle("轉賬匯款");
break;
case 4:
initFragment5();
setTitle("我的賬戶");
break;
case 5:
initFragment1();
setTitle("安全中心");
break;
case 6:
initFragment2();
setTitle("特色服務");
break;
case 7:
initFragment3();
setTitle("投資理財");
break;
case 8:
initFragment4();
setTitle("轉賬匯款");
break;
case 9:
initFragment5();
setTitle("我的賬戶");
break;
}
}
@Override
public void itemCenterClick(View view) {
Toast.makeText(MainActivity.this,
"you can do something just like ccb ",
Toast.LENGTH_SHORT).show();
}
});
}
//顯示第一個fragment
private void initFragment1(){
//開啟事務,fragment的控制是由事務來實現的
homepageFragment = new HomepageFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_tv,homepageFragment);
transaction.addToBackStack(null);
transaction.commit();
}
//顯示第二個fragment
private void initFragment2(){
//開啟事務,fragment的控制是由事務來實現的
settingFragment = new SettingFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_tv,settingFragment);
transaction.addToBackStack(null);
transaction.commit();
}
private void initFragment3(){
//開啟事務,fragment的控制是由事務來實現的
historyFragment = new HistoryFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_tv,historyFragment);
transaction.addToBackStack(null);
transaction.commit();
}
private void initFragment4(){
//開啟事務,fragment的控制是由事務來實現的
fourthFragment = new FourthFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_tv,fourthFragment);
transaction.addToBackStack(null);
transaction.commit();
}
private void initFragment5(){
//開啟事務,fragment的控制是由事務來實現的
fifthFragment = new FifthFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_tv,fifthFragment);
transaction.addToBackStack(null);
transaction.commit();
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK
&& event.getRepeatCount() == 0) {
finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
/**
* 設置布局的寬高,並策略menu item寬高
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int resWidth = 0;
int resHeight = 0;
double startAngle = mStartAngle;
double angle = 360 / 10; //我們傳入了10個孩子
/**
* 根據傳入的參數,分別獲取測量模式和測量值
*/
int width = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
/**
* 如果寬或者高的測量模式非精確值
*/
if (widthMode != MeasureSpec.EXACTLY
|| heightMode != MeasureSpec.EXACTLY) {
// 主要設置為背景圖的高度
resWidth = getDefaultWidth();
resHeight = (int) (resWidth * DEFAULT_BANNER_HEIGTH /
DEFAULT_BANNER_WIDTH);
} else {
// 如果都設置為精確值,則直接取小值;
resWidth = resHeight = Math.min(width, height);
}
setMeasuredDimension(resWidth, resHeight);
// 獲得直徑
mRadius = Math.max(getMeasuredWidth(), getMeasuredHeight());
// menu item數量
final int count = getChildCount();
// menu item尺寸
int childSize;
// menu item測量模式
int childMode = MeasureSpec.EXACTLY;
// 迭代測量:根據孩子的數量進行遍歷,為每一個孩子測量大小,設置監聽回調。
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
startAngle = startAngle % 360;
if (startAngle > 269 && startAngle < 271 && isTouchUp) {
mOnMenuItemClickListener.itemClick(i); //設置監聽回調。
mCurrentPosition = i; //本次使用mCurrentPosition,只是把他作為一個temp變量,可以有更多的使用,比如動態設置每個孩子相隔的角度
childSize = DensityUtil.dip2px(getContext(), RADIO_TOP_CHILD_DIMENSION);//設置大小
} else {
childSize = DensityUtil.dip2px(getContext(), RADIO_DEFAULT_CHILD_DIMENSION);//設置大小
}
if (child.getVisibility() == GONE) {
continue;
}
// 計算menu item的尺寸;以及和設置好的模式,去對item進行測量
int makeMeasureSpec = -1;
makeMeasureSpec = MeasureSpec.makeMeasureSpec(childSize,
childMode);
child.measure(makeMeasureSpec, makeMeasureSpec);
startAngle += angle;
}
//item容器內邊距
mPadding = DensityUtil.dip2px(getContext(), RADIO_MARGIN_LAYOUT);
}
/**
* 設置menu item的位置
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int layoutRadius = mRadius;
// Laying out the child views
final int childCount = getChildCount();
int left, top;
// menu item 的尺寸
int cWidth;
// 根據menu item的個數,計算角度
float angleDelay = 360 / 10;
// 遍歷去設置menuitem的位置
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
//根據孩子遍歷,設置中間頂部那個的大小以及其他圖片大小。
if (mStartAngle > 269 && mStartAngle < 271 && isTouchUp) {
cWidth = DensityUtil.dip2px(getContext(), RADIO_TOP_CHILD_DIMENSION);
child.setSelected(true);
} else {
cWidth = DensityUtil.dip2px(getContext(), RADIO_DEFAULT_CHILD_DIMENSION);
child.setSelected(false);
}
if (child.getVisibility() == GONE) {
continue;
}
//大於360就取余歸於小於360度
mStartAngle = mStartAngle % 360;
float tmp = 0;
//計算圖片布置的中心點的圓半徑。就是tmp
tmp = layoutRadius / 2f - cWidth / 2 - mPadding;
// tmp cosa 即menu item中心點的橫坐標。計算的是item的位置,是計算位置!!!
left = layoutRadius
/ 2
+ (int) Math.round(tmp
* Math.cos(Math.toRadians(mStartAngle)) - 1 / 2f
* cWidth) + DensityUtil
.dip2px(getContext(), 1);
// tmp sina 即menu item的縱坐標
top = layoutRadius
/ 2
+ (int) Math.round(tmp
* Math.sin(Math.toRadians(mStartAngle)) - 1 / 2f * cWidth) + DensityUtil
.dip2px(getContext(), 8);
//接著當然是布置孩子的位置啦,就是根據小圓的來布置的
child.layout(left, top, left + cWidth, top + cWidth);
// 疊加尺寸
mStartAngle += angleDelay;
}
}

//dispatchTouchEvent是處理觸摸事件分發,事件(多數情況)是從Activity的dispatchTouchEvent開始的。執行super.dispatchTouchEvent(ev),事件向下分發。
//onTouchEvent是View中提供的方法,ViewGroup也有這個方法,view中不提供onInterceptTouchEvent。view中默認返回true,表示消費了這個事件。
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
getParent().requestDisallowInterceptTouchEvent(true);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//直接就是獲取x,y值了,還有一個DownTime(附送)
mLastX = x;
mLastY = y;
mDownTime = System.currentTimeMillis();
mTmpAngle = 0;
break;
case MotionEvent.ACTION_MOVE:
isTouchUp = false; //注意isTouchUp 這個標記量!!!
/**
* 獲得開始的角度
*/
float start = getAngle(mLastX, mLastY);
/**
* 獲得當前的角度
*/
float end = getAngle(x, y);
// 如果是一、四象限,則直接end-start,角度值都是正值
if (getQuadrant(x, y) == 1 || getQuadrant(x, y) == 4) {
mStartAngle += end - start;
mTmpAngle += end - start;//按下到抬起時旋轉的角度
} else
// 二、三象限,色角度值是負值
{
mStartAngle += start - end;
mTmpAngle += start - end;
}
// 重新布局
if (mTmpAngle != 0) {
requestLayout();
}
mLastX = x;
mLastY = y;
break;
case MotionEvent.ACTION_UP:
//當手指UP啦,就是關鍵啦,一個緩沖角度,即我們將要固定幾個位置,而不是任意位置。我們要設計一個可能的角度去自動幫他選擇。
backOrPre();
break;
}
return super.dispatchTouchEvent(event);
}
private void backOrPre() { //緩沖的角度。即我們將要固定幾個位置,而不是任意位置。我們要設計一個可能的角度去自動幫他選擇。
isTouchUp = true;
float angleDelay = 360 / 10; //這個是每個圖形相隔的角度
//我們本來的上半圓的圖片角度應該是:18,54,90,126,162。所以我們這裡是:先讓當前角度把初始的18度減去再取余每個圖形相隔角度。得到的是什麼呢?就是一個圖片本來應該在的那堆角度。所以如果是就直接return了。
if ((mStartAngle-18)%angleDelay==0){
return;
}
float angle = (float)((mStartAngle-18)%36); //angle就是那個不是18度開始布局,然後是36度的整數的多出來的部分角度
//以下就是我們做的緩沖角度處理啦,如果多出來的部分角度大於圖片相隔角度的一半就往前進一個,如果小於則往後退一個。
if (angleDelay/2 > angle){
mStartAngle -= angle;
}else if (angleDelay/2<angle){ mstartangle="mStartAngle" -="" angle="" pre="" data-cke-pa-onlayout="">
App的打磨之路(上)
前言:俗話說磨刀不誤砍柴工,一個優秀的產品從一個不錯的點子直到用戶的手中,是需要一個團隊不遺余力協同合作不斷打磨出來的;同樣,一個好的App除正常的代碼編寫外,還需要經過
Android 源碼系列之(十一)從源碼的角度深入理解AccessibilityService,打造自己的APP小外掛(下)
在上篇文章Android 源碼系列之<十>從源碼的角度深入理解AccessibilityService,打造自己的APP小外掛(上)中我們講解了通過Acces
[Android Studio] *.jar 與 *.aar 的生成與*.aar導入項目方法
主要講解Android Studio中生成aar文件以及本地方式使用aar文件的方法。 在Android Studio中對一個自己庫進行生成操作時將會同時生成*.jar與
使用Robolectric對Android應用進行單元測試
介紹Robolectric主要從框架簡介、框架優點、框架可行性分析,框架環境配置、框架演示、框架參考資料方面進行介紹:一、框架簡介官網的介紹Running tests o