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);
    }
}
时间: 2024-11-05 13:26:48

Android5.0开发范例大全 读书笔记(二)的相关文章

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

(六)与系统交互 6.1后台通知 1.关于后台通知,下面展示6种样式.值得一提的是,笔者的小米5只能显示基本样式,雷军真是良心厂商啊. 2.首先上布局xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="

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

(二)用户交互 2.14转发触摸事件 1.TouchDelegate很适合简单的触摸转发,它指定任意的矩形区域来向小视图转发触摸事件,其缺点是每个被转发的事件都会转发到代理视图的中间位置 public class TouchDelegateLayout extends FrameLayout { public TouchDelegateLayout(Context context) { this(context, null); } public TouchDelegateLayout(Conte

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

(四)实现设备硬件交互与媒体交互 4.6自定义摄像头覆盖层 1.将Camera中的内容实时的绘制到SurfaceView中 若要自定义拍摄界面,只要重新定义surface的界面即可 以下展示全部代码 public class PreviewActivity extends AppCompatActivity implements SurfaceHolder.Callback { Camera mCamera; SurfaceView mPreview; @Override protected v

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

(三)通信和联网 3.1显示Web信息 1.WebView通过loadUrl()方法直接访问网页时,点击跳转链接会打开系统默认的浏览器,若要拦截WebView事件,可为其添加WebViewClient webView.setWebViewClient(new WebViewClient()) 2.WebView默认不支持JavaScript,要通过setJavaScriptEnabled()进行设置 webView.getSettings().setJavaScriptEnabled(true)

《How Tomcat Works》读书笔记(二)

<How Tomcat Works>读书笔记(二) 这是<How Tomcat Works>第一二章的读书笔记.第一张主要写了一个静态资源处理的web服务器,第二章加了对servlet的处理. 1. 概述 1.1 架构 HttpServer:表示Http服务器,与客户端通信,处理Http请求. StaticResourceProcessor:对静态资源请求进行处理. ServletProcessor:对Servlet资源请求进行处理. Request:表示Http请求,实现了Ser

JavaScript、jQuery、HTML5、Node.js实例大全-读书笔记2

技术很多,例子很多,只好慢慢学,慢慢实践!!现在学的这本书是[JavaScript实战----JavaScript.jQuery.HTML5.Node.js实例大全] JavaScript.jQuery.HTML5.Node.js实例大全-读书笔记1 3.2 照片加载与定位 根据功能设计,可以先写好 HTML 结构基础,再配好 CSS 做出大致效果,最后用 JavaScript加上各种动作.首先请看 HTML 代码结构. 3.2.1 HTML 代码 CSS代码保存到 eg3.css 文件中,Ja

《卓有成效的程序员》----读书笔记二

六大方面对比Launchy和TypeAndRun(TAR) 对于快速启动工具,很多人都有自己的偏好,多次听到朋友介绍Launchy的好,虽然自己一直在使用着TAR,还是克制不住对于好软件的渴求,下载Launchy进行试用.很多软件都是有一个试用期的,也许新的软件确实不错,但是你习惯了以前使用的那个软件.今天就比较客观的将Launchy和TAR进行一下对比,从界面.上手速度到功能.自定义,以及软件的稳定性.占用资源进行详细的比较. [界面美观]Launchy:毫无疑问这是它的强项.1.0正式版自带

《Programming in Lua 3》读书笔记(二十二)

日期:2014.8.6 PartⅣ The C API 26 Extending Your Application 使用Lua很重要的一点是用来做配置语言.配合主语言做一些功能的配置. 26.1 The Basics 有的时候程序需要配置一些功能信息,很多时候可能有许多别的方法比用lua做配置要更简单:如使用环境变量或者读取文件,读取文件涉及到文件的解析.如果使用Lua进行配置的话,相当于用lua文件替代了要读取的如csv.txt文件等. 使用Lua进行配置的时候,就需要使用Lua API去控制

《R实战》读书笔记二

第一章 R简介 本章概要 1安装R 2理解R语言 3运行R程序 本章所介绍的内容概括如下. 一个典型的数据分析步骤如图1所示. 图1:典型数据分析步骤 简而言之,现今的数据分析要求我们从多种数据源中获取数据.数据合并.标注.清洗和分析,并且把分析的结果进行展示,形成报告或者系统,辅助决策.R能够满足现今数据分析的要求. 为什么用R? R是一个适合统计分析和绘图的环境与语言.它是开源.免费的,获得世界范围社区支持.统计分析和绘图工具已经很多了,例如:SPSS,SAS,Excel,Stata和Min