Android5.0开发范例大全 读书笔记

宝剑锋从磨砺出,梅花香自苦寒来。这篇文章主要讲述Android5.0开发范例大全 读书笔记相关的知识,希望能为你提供帮助。
(二)用户交互
  2.1ActionBar
1.首先,调用onCreateOptionsMenu(Menu menu)方法为actionbar设置样式

@Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.support,menu); return true; }

  res/menu/support.xml如下
< ?xml version="1.0" encoding="utf-8"?> < menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> < item android:id="@+id/action_delete" android:icon="@android:drawable/ic_menu_delete" app:showAsAction="ifRoom" android:title="delete" /> < item android:id="@+id/action_setting" android:showAsAction="never" android:orderInCategory="100" android:title="action_setting" /> < /menu>

  接着,若Activity继承自AppCompatActivity,则调用代码
android.support.v7.app.ActionBar actionBar=getSupportActionBar();

  否则直接调用
ActionBar actionBar=getActionBar();

  2.2ToolBar
如今Google官方推荐使用Toolbar替代ActionBar
1.首先在XML中定义资源,要注意主题颜色,因为Toolbar默认不会自动继承当前material design的风格
< android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/colorAccent" app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

  接着在代码中将toolbar集成
Toolbar toolbar= (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar);

  2.3动态方向锁定
1.通过setRequestedOrientation()方法实现,首先设置一个tooglebutton来设置是否锁定
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_orientation); toggleButton = (ToggleButton) findViewById(R.id.tb_orientation); assert toggleButton != null; if(getRequestedOrientation()!= ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED){ toggleButton.setChecked(true); }else{ toggleButton.setChecked(false); } toggleButton.setOnCheckedChangeListener(this); }

  接着在监听器中对屏幕方向进行动态的设置
@Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { int current=getResources().getConfiguration().orientation; if(isChecked){ switch (current){ case Configuration.ORIENTATION_LANDSCAPE: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); break; case Configuration.ORIENTATION_PORTRAIT: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); break; default: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); } }else{ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); } }

  2.5创建上下文动作
  1.对于单个项相关上下文,使用PopupMenu
  首先自定义ContextListItem类以封装PopupMenu
public class ContextListItem extends LinearLayout implements PopupMenu.OnMenuItemClickListener, View.OnClickListener {private PopupMenu mPopupMenu; private TextView mTextView; public ContextListItem(Context context) { this(context,null); }public ContextListItem(Context context, AttributeSet attrs) { this(context, attrs, 0); }public ContextListItem(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }@Override public boolean onMenuItemClick(MenuItem item) { String string=mTextView.getText().toString(); switch (item.getItemId()){ case R.id.action_delete: Toast.makeText(getContext(), "delete"+string,Toast.LENGTH_SHORT).show(); break; case R.id.action_setting: Toast.makeText(getContext(), "edit"+string,Toast.LENGTH_SHORT).show(); break; } return true; }@Override protected void onFinishInflate() { super.onFinishInflate(); mTextView= (TextView) findViewById(R.id.text); View contextButton=findViewById(R.id.context); contextButton.setOnClickListener(this); mPopupMenu=new PopupMenu(getContext(),contextButton); mPopupMenu.setOnMenuItemClickListener(this); mPopupMenu.inflate(R.menu.support); }

    其中,list_item.xml如下
< ?xml version="1.0" encoding="utf-8"?> < com.vastsum.joshua.android50.day20160927.ContextListItem xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="?android:attr/listPreferredItemHeightSmall" android:orientation="horizontal" android:paddingLeft="?android:attr/listPreferredItemPaddingLeft" android:paddingRight="?android:attr/listPreferredItemPaddingRight" android:background="?android:attr/activatedBackgroundIndicator" > < TextView android:id="@+id/text" android:layout_width="0dp" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceListItemSmall" android:layout_weight="1" android:layout_gravity="center_vertical"/> < ImageView android:id="@+id/context" style="@style/Widget.AppCompat.Light.ActionButton.Overflow" android:layout_width="?android:attr/listPreferredItemHeightSmall" android:layout_height="match_parent" android:clickable="true" android:focusable="false" /> < /com.vastsum.joshua.android50.day20160927.ContextListItem>

2.如果会影响多个项,则可以启用ActionMode来响应用户动作,下面展示二者相结合的完整代码
public class ActionActivity extends AppCompatActivity implements AbsListView.MultiChoiceModeListener { private static final String[] ITEMS = {"MOM", "DAD", "MOM", "DAD", "MOM", "DAD", "MOM", "DAD", "MOM", "DAD"}; private ListView mList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mList = new ListView(this); ArrayAdapter< String> adapter = new ArrayAdapter< String> (this, R.layout.list_item, R.id.text, ITEMS); mList.setAdapter(adapter); mList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); mList.setMultiChoiceModeListener(this); setContentView(mList, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); mList.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView< ?> parent, View view, int position, long id) { startActionMode(ActionActivity.this); } }); }@Override public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { int count = mList.getCheckedItemCount(); mode.setTitle(String.format("%d Select", count)); }@Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { MenuInflater inflater = mode.getMenuInflater(); inflater.inflate(R.menu.support, menu); return true; }@Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return true; }@Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { return true; }@Override public void onDestroyActionMode(ActionMode mode) {}}

2.8自定义BACK键
1.之前实现返回功能都是直接调用activity的finish()方法,现在发现可以调用
super.onBackPressed()

2.在默认情况下,UI中添加Fragment的操作不会再任务的回退栈中添加相应的Fragment,因此back键不能回退。
  因此,首先要通过FragmentTransaction的addToBackStack()方法将fragment添加到回退栈
ft=getFragmentManager().beginTransaction(); ft.add(R.id.fl, MyFragment.newInstance("Second")); ft.addToBackStack("Second"); ft.commit();

  接着调用FragmentTransaction的popBackStack()方法将fragment弹出
public void back(View view) { getFragmentManager().popBackStack(); }

  顺便复习一下fragment的用法
public static class MyFragment extends Fragment{ private String title; public static MyFragment newInstance(String title){ MyFragment fragment= new MyFragment(); fragment.setTitle(title); return fragment; }@Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { TextView textView=new TextView(getActivity()); textView.setText(title); return textView; }public void setTitle(String title) { this.title = title; } }

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_back); ft = getFragmentManager().beginTransaction(); ft.add(R.id.fl, MyFragment.newInstance("First")); ft.commit(); }

2.10监控TextView的变动
1.创建一个Watcher实现TextWatcher接口
public class CurrencyTextWatcher implements TextWatcher { boolean mEditing; public CurrencyTextWatcher() { mEditing = false; }@Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {}@Override public void onTextChanged(CharSequence s, int start, int before, int count) {}@Override public synchronized void afterTextChanged(Editable s) { if (!mEditing) { mEditing = true; String digits = s.toString().replaceAll("\\D", ""); NumberFormat nf = NumberFormat.getCurrencyInstance(); try { String formatted = nf.format(Double.parseDouble(digits) / 100); s.replace(0, s.length(), formatted); } catch (NumberFormatException n) { s.clear(); } mEditing = false; } } }

2.在Activity中设置Watcher监听
editText.addTextChangedListener(new CurrencyTextWatcher());

2.12消除软键盘
1.在特定的用户信息录入界面很有用处
public void hide(View view) { InputMethodManager imm= (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(view.getWindowToken(),0); }

2.13处理复杂的触摸事件
  talk is cheap ,show you the code!
1.实现自定义的一个scrollview
public class PanGestureScrollView extends FrameLayout { private GestureDetector mDetector; private Scroller mScroller; private float mInitialX, mInitialY; private int mTouchSlop; public PanGestureScrollView(Context context) { this(context, null); }public PanGestureScrollView(Context context, AttributeSet attrs) { this(context, attrs, 0); }public PanGestureScrollView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); }private void init(Context context) {mDetector = new GestureDetector(context, mListener); mScroller = new Scroller(context); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); }@Override protected void measureChild(View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec) { int childWidthMeasureSpec; int childHeightMeasureSpec; childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); child.measure(childWidthMeasureSpec, childHeightMeasureSpec); }@Override protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed) { final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.leftMargin + lp.rightMargin, MeasureSpec.UNSPECIFIED); final int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(lp.topMargin + lp.bottomMargin, MeasureSpec.UNSPECIFIED); child.measure(childWidthMeasureSpec, childHeightMeasureSpec); }private GestureDetector.SimpleOnGestureListener mListener = new GestureDetector.SimpleOnGestureListener() { @Override public boolean onDown(MotionEvent e) { if (!mScroller.isFinished()) { mScroller.abortAnimation(); } return true; }@Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { fling((int) -velocityX / 3, (int) -velocityY / 3); return true; }@Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { scrollBy((int) distanceX, (int) distanceY); return true; } }; private void fling(int i, int i1) { if (getChildCount() > 0) { int height = getHeight() - getPaddingBottom() - getPaddingTop(); int width = getWidth() - getPaddingLeft() - getPaddingRight(); int bottom = getChildAt(0).getHeight(); int right = getChildAt(0).getWidth(); mScroller.fling(getScrollX(), getScrollY(), i, i1, 0, Math.max(0, right - width), 0, Math.max(0, bottom - height)); invalidate(); } }private int clamp(int n, int my, int child) { if (my > = child || n < 0) { return 0; } if ((my + n) > child) { return child - my; } return n; }@Override public void computeScroll() { if (mScroller.computeScrollOffset()) { int oldX = getScrollX(); int oldY = getScrollY(); int x = mScroller.getCurrX(); int y = mScroller.getCurrY(); if (getChildCount() > 0) { View child = getChildAt(0); x = clamp(x, getWidth() - getPaddingRight() - getPaddingLeft(), child.getWidth()); y = clamp(y, getHeight() - getPaddingBottom() - getPaddingTop(), child.getHeight()); if (x != oldX || y != oldY) { scrollTo(x, y); } }} postInvalidate(); }@Override public void scrollTo(int x, int y) { if(getChildCount()> 0){ View child=getChildAt(0); x = clamp(x, getWidth() - getPaddingRight() - getPaddingLeft(), child.getWidth()); y = clamp(y, getHeight() - getPaddingBottom() - getPaddingTop(), child.getHeight()); if(x!=getScrollX()||y!=getScrollY()){ super.scrollTo(x,y); } } }@Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()){ case MotionEvent.ACTION_DOWN: mInitialX=ev.getX(); mInitialY=ev.getY(); mDetector.onTouchEvent(ev); break; case MotionEvent.ACTION_MOVE: final float x=ev.getX(); final float y=ev.getY(); final int yDiff= (int) Math.abs(y-mInitialY); final int xDiff= (int) Math.abs(x-mInitialX); if(yDiff> mTouchSlop||xDiff> mTouchSlop){ return true; } break; } return super.onInterceptTouchEvent(ev); }@Override public boolean onTouchEvent(MotionEvent event) { return mDetector.onTouchEvent(event); } }

【Android5.0开发范例大全 读书笔记】 


    推荐阅读