編輯:關於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除正常的代碼編寫外,還需要經過
在上篇文章Android 源碼系列之<十>從源碼的角度深入理解AccessibilityService,打造自己的APP小外掛(上)中我們講解了通過Acces
主要講解Android Studio中生成aar文件以及本地方式使用aar文件的方法。 在Android Studio中對一個自己庫進行生成操作時將會同時生成*.jar與
介紹Robolectric主要從框架簡介、框架優點、框架可行性分析,框架環境配置、框架演示、框架參考資料方面進行介紹:一、框架簡介官網的介紹Running tests o