• 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);
        }
    }
  • 相关阅读:
    不完全恢复用例
    全自动 TSPITR基于RMANSCN
    restore和recover的区别
    DG不同机器自己总结
    将10g RAC库用rman 的方式备份并恢复到异机 刚试验通过与大家分享
    Linux RH5平台下使用Oracle ASM创建数据库
    crs_stat状态失败后unregister掉相关进程
    ocr is not shared across all the nodes in the clus
    RMAN 备份与恢复 实例
    基于LINUX的Oracle+10G+RAC管理维护
  • 原文地址:https://www.cnblogs.com/xx-wqj/p/5986033.html
Copyright © 2020-2023  润新知