zoukankan      html  css  js  c++  java
  • 20189200余超 2018-2019-2 移动平台应用开发实践第七周作业

    20189200余超 2018-2019-2 移动平台应用开发实践第七周作业

    布局

    在这一节中首先学习了java的页面布局,在此基础之上来进行了编程。
    图片如下:

    代码如下

    **
     * 使用代码进行登录界面的布局
     * @author yuchao
     */
    public class CodeLayoutActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //创建一个最外层的根布局
            LinearLayout rootLayout = new LinearLayout(this);
            rootLayout.setBackgroundColor(Color.CYAN);
    
            //设置线性布局中子View的摆放为竖直方向
            rootLayout.setOrientation(LinearLayout.VERTICAL);
            //创建一个根部局的LayoutParams
            LinearLayout.LayoutParams rootParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
            //设置根部局的Margin值
            rootParams.setMargins(DensityUtil.dip2px(this,5),DensityUtil.dip2px(this,5),DensityUtil.dip2px(this,5),DensityUtil.dip2px(this,5));
            rootParams.gravity = Gravity.CENTER_HORIZONTAL;
            rootLayout.setLayoutParams(rootParams);
            //设置最外层根部局布局的背景颜色
            rootLayout.setBackgroundColor(Color.CYAN);
            //将当前创建的根部局设置给Activity
            setContentView(rootLayout);
    
    
            //创建一个显示用户头像的ImageView
            ImageView ivIco = new ImageView(this);
            ivIco.setImageResource(R.drawable.ico);
            //将创建的用于显示头像的ImageView添加到最外层的线性布局中
            rootLayout.addView(ivIco);
            //当通过子View进行获取所在的布局的时候,rootLayout.addView(ivIco)需要写在前面,原因想起来也很清楚,当前的ImageView都还没有添加到父View如果直接通过getLayoutParams()当然会出先空指针异常(可以查看源码)
            LinearLayout.LayoutParams ivParams = (LinearLayout.LayoutParams) ivIco.getLayoutParams();
            //给用于显示头像的ImageView设置宽高
            ivParams.width = DensityUtil.dip2px(this,100f);
            ivParams.height = DensityUtil.dip2px(this,100f);
            //设置居中的方式(子View在父View下的摆放方式为水平居中)
            ivParams.gravity = Gravity.CENTER_HORIZONTAL;
            ivParams.setMargins(0,DensityUtil.dip2px(this,100),0,0);
            ivIco.setLayoutParams(ivParams);
    
    
    
            //创建水平排列的线性布局,用于放置账户相关的View
            LinearLayout userCountLayout = new LinearLayout(this);
            userCountLayout.setOrientation(LinearLayout.HORIZONTAL);
            //将当前的创建的线性布局添加到根View
            rootLayout.addView(userCountLayout);
    
    
            //显示用户名的TextView
            TextView tvShowUser = new TextView(this);
            tvShowUser.setText("用户名:");
            userCountLayout.addView(tvShowUser);
            LinearLayout.LayoutParams userCountlayoutParams = (LinearLayout.LayoutParams) tvShowUser.getLayoutParams();
            userCountlayoutParams.setMargins(DensityUtil.dip2px(this,20),DensityUtil.dip2px(this,20),DensityUtil.dip2px(this,20),DensityUtil.dip2px(this,20));
    
    
            //创建用于填写用户账户的EditText
            EditText edtUserCount = new EditText(this);
            userCountLayout.addView(edtUserCount);
            edtUserCount.setHint("请输入用户名");
            LinearLayout.LayoutParams edtUserCountlayoutParams = (LinearLayout.LayoutParams) edtUserCount.getLayoutParams();
            edtUserCount.setWidth(0);
            edtUserCountlayoutParams.weight = 1;
            //父View的Gravity属性,确定子View的摆放规则
            edtUserCountlayoutParams.gravity = Gravity.CENTER_VERTICAL;
            //View.setGravity方法相当于  android:gravity="center",该属性表示对View中内容进行的限定
    //        edtUserCount.setGravity(Gravity.CENTER);
    
    
            //创建线性布局用于容纳密码相关的View
            LinearLayout pwdLayout =  new LinearLayout(this);
            pwdLayout.setGravity(LinearLayout.HORIZONTAL);
            LinearLayout.LayoutParams pwdLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT);
            pwdLayout.setLayoutParams(pwdLayoutParams);
            rootLayout.addView(pwdLayout);
    
            //TextView显示密码文本
            TextView tvShowPwd = new TextView(this);
            tvShowPwd.setText("密    码:");
            pwdLayout.addView(tvShowPwd);
            LinearLayout.LayoutParams tvShowPwdParams = (LinearLayout.LayoutParams) tvShowPwd.getLayoutParams();
            tvShowPwdParams.setMargins(DensityUtil.dip2px(this,20),DensityUtil.dip2px(this,20),DensityUtil.dip2px(this,20),DensityUtil.dip2px(this,20));
            tvShowPwdParams.gravity = Gravity.CENTER_VERTICAL;
    
            //EdtText用于输入密码
            EditText edtPwd = new EditText(this);
            edtPwd.setHint("请输入密码");
            pwdLayout.addView(edtPwd);
            //使用new的方式来获取 LayoutParams
            LinearLayout.LayoutParams edtPwdParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            //设置权重
            edtPwdParams.weight = 1;
            edtPwdParams.width = 0;
            //将布局参数设置给EdtText
            edtPwd.setLayoutParams(edtPwdParams);
    
            //用于进行登录的button
            Button btnLogin = new Button(this);
            btnLogin.setText("登陆");
            rootLayout.addView(btnLogin);
            LinearLayout.LayoutParams btnLoginParams = (LinearLayout.LayoutParams) btnLogin.getLayoutParams();
            //设置Button的大小
            btnLoginParams.width = LinearLayout.LayoutParams.WRAP_CONTENT;
            btnLoginParams.height= LinearLayout.LayoutParams.WRAP_CONTENT;
            btnLoginParams.gravity = Gravity.CENTER_HORIZONTAL;
    

    监听器

    全局监听器
    其实只是把每个创建的监听器添加入List里 当SDK里调用一次的时候 遍历所有的监听器 执行每个监听器的这个方法就行了
    好吧 其实就是观察者模式啦
    1.首先写一个监听器的接口

    public interface testSDKListener {
    
        public void test(String str);
    
    }
    
    

    2.写这个监听器的实现方法

    public class testSDKListenerImpl {
    
        private testSDKListener m_listener;
    
        public void setListener(testSDKListener listener) {
            m_listener = listener;
        }
    
        public void test(String str) {
            if (m_listener != null) {
                m_listener.test(str);
            }
        }
    }
    

    3.创建一个List 然后把所有创建的监听器都加进去 在执行的时候遍历所有监听器

    public class testSDKListenerList {
    
        private static testSDKListenerList instance;
    
        private List<testSDKListener> listeners;
    
        public static testSDKListenerList getInstance() {
            if (instance == null) {
                instance = new testSDKListenerList();
            }
            return instance;
        }
    
        private testSDKListenerList() {
            listeners = new ArrayList<testSDKListener>();
        }
    
        public void setSDKListener(testSDKListener listener) {
            if (!listeners.contains(listener) && listener != null) {
                Log.i("testSDKListenerList", "Add a listener!");
                this.listeners.add(listener);
            }
        }
    
        public void test(String str) {
            for (testSDKListener listener : listeners) {
                listener.test(str);
            }
        }
    }
    

    4.在主程序中创建监听器

    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            testSDKListenerList.getInstance().setSDKListener(new testSDKListener() {
    
                @Override
                public void test(String str) {
                    Log.d("Listener.test", "str="+str);
                }
            });
      
    

    5.在SDK中执行监听器的方法

    testSDKListenerList.getInstance().test("test success!");
    

    操作栏

    一般来说,Android 默认的状态栏样式表现为黑底白字,如果我们应用的标题栏背景色也为黑色,那就能与状态栏很好地衔接在一起,体验极佳。反之,如果为其他的颜色,整个界面的呈现效果就会大打折扣。

    幸运的是,Android 4.4 版本开始,系统提供了相应的 API,支持状态栏全透明化,界面 Content View 可以延伸到状态栏上,填充状态栏背景色。而在 Android 5.0 版本开始,系统在此基础上做了进一步优化和规范,能够实现动态改变状态栏背景色,在透明度上默认呈现为半透明化,可定制化程度更高。

    在此基础上,最终要做到我们的应用呈现在 Android 各个系统版本上的效果如图所示:

    关于 Android 4.4 版本开始的状态栏变化,许多人喜欢称之为“沉浸式状态栏”,但从系统提供的 API 命名上可以看出,核心词汇为 “Translucent”,故准确来讲,这种效果又应该称之为“透明状态栏”。知乎上对于这两种叫法也颇有争议,具体内容可参考话题:为什么在国内会有很多用户把「透明栏」(Translucent Bars)称作 「沉浸式顶栏」?。可能对于设计师而言,沉浸式还是透明式的称呼有所区别,但对于广大开发者而言,无足轻重,我们所关注的应该是如何实现这种效果,并能够很好的兼容到各个版本中。

    使用案例分析
    res/values/styles 文件中定义基础主题样式:

    <style name="BaseTheme" parent="Theme.AppCompat.Light.NoActionBar"/>
        <style name="AppTheme" parent="BaseTheme">
        </style>
    

    res/values-v19/styles 文件中定义兼容主题样式:

    <style name="AppTheme" parent="BaseTheme">
            <item name="android:windowTranslucentStatus">true</item>
        </style>
    

    然后在 AndroidManifest.xml 文件中使用全局主题样式:

    <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="Samples"
            android:supportsRtl="true"
            android:name=".MyApplication"
            android:theme="@style/AppTheme">
    

    新建一个 layout 布局文件,单独定义 toolbar 内容,在应用中的其他 Activity 界面布局中使用 include 标签潜入引用:

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/tb_toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="?actionBarSize"
        android:background="@color/colorPrimary"
        android:fitsSystemWindows="true"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:title="@string/app_name"
        app:titleTextColor="@android:color/white">
    
    </android.support.v7.widget.Toolbar>
    

    这里使用 android:fitsSystemWindows="true" 属性解决内容试图向上延伸的问题。实际上,也可以使用 android:paddingTop="@dimen/toolbar_padding_top" 的方式解决,toolbar_padding_top 间距为状态栏高度,在大多数机器上状态栏高度为 25dp,当然也可以通过代码动态获取状态栏高度并设置到 Toolbar 的 paddingTop 属性上。需要注意的是,这里要做兼容判断,比如在 res/values/dimens.xml 中定义toolbar_padding_top 高度为 0dp,在 res/values-v19/dimens.xml 中为 25dp,确保兼容 Android 4.4 以下版本。

    基本上,做到这些就能够实现文章开头处图中的效果。值得注意的是,有时候如果想在 Android 5.0 及以上版本的系统中也做到全透明效果,或者说状态栏与导航栏的颜色一致,还可以做进一步兼容处理,毕竟自 5.0 版本开始,系统对于状态栏背景色的定制提供了更好的 API。如 res/values-v21/styles.xml 中定义:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <style name="AppTheme" parent="BaseTheme">
            <item name="android:colorPrimary">@color/colorPrimary</item>
            <item name="android:colorPrimaryDark">@color/colorPrimary</item>
            <item name="android:colorAccent">@color/colorAccent</item>
        </style>
    

    上下文菜单

    当用户长按Activity页面时,弹出的菜单我们称为上下文菜单。我们经常在Windows中用鼠标右键单击弹出的菜单就是上下文菜单。

    ContextMenu与OptionMenu的区别:
    1、OptionMenu对应的是activity,一个activity只能拥有一个选项菜单;
    2、ContextMenu对应的是view,每个view都可以设置上下文菜单;
    3、一般情况下ContextMenu常用语ListView或者GridView

    实现步骤:
    (1)首先给View注册上下文菜单registerForContextMenu()
    this.registerForContextMenu(contextView);
    (2)添加上下文菜单的内容onCreateContextMenu()



    代码:

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.jiapeng.munedemo.MainActivity"
        tools:ignore="MergeRootFrame" >
    
        <ListView
            android:id="@+id/mune_list"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >
        </ListView>
    
    </FrameLayout>
    
    protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            showListView();
            // 注册上下文菜单
            this.registerForContextMenu(listview);
        }
    
        /**
         * 加载数据
         */
        private void showListView() {
            listview = (ListView) findViewById(R.id.mune_list);
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                    android.R.layout.simple_list_item_1, getDate());
            listview.setAdapter(adapter);
    
        }
    
        /**
         * 创建数据源
         * 
         * @return list
         */
        private ArrayList<String> getDate() {
            ArrayList<String> list = new ArrayList<String>();
            for (int i = 0; i < 10; i++) {
                list.add("菜单" + i);
            }
            return list;
        }
    
        /**
         * 添加上下文菜单的菜单项
         */
        public void onCreateContextMenu(ContextMenu menu, View v,
                ContextMenuInfo menuInfo) {
            menu.setHeaderTitle("上下文菜单");
            menu.setHeaderIcon(R.drawable.ic_launcher);
            //加载上下文菜单内容
            menu.add(1, 1, 1, "保存");
            menu.add(1, 2, 1, "更改");
            menu.add(1, 3, 1, "删除");
            super.onCreateContextMenu(menu, v, menuInfo);
        }
    
        /**
         * 创建单击事件
         */
        public boolean onContextItemSelected(MenuItem item) {
            switch (item.getItemId()) {
            case 1:
                Toast.makeText(this, "点击了保存", Toast.LENGTH_SHORT).show();
                break;
            case 2:
                Toast.makeText(this, "点击了更改", Toast.LENGTH_SHORT).show();
                break;
            case 3:
                Toast.makeText(this, "点击了删除", Toast.LENGTH_SHORT).show();
                break;
    
            default:
                break;
            }
            return super.onContextItemSelected(item);
        }
    

  • 相关阅读:
    我们怎么才能变为综合才能型程序员
    Beyond Compare乱码问题汇总
    Navicat Premium 批处理作业转换有哪些方法
    Beyond Compare基本用法
    Navicat Premium 表查看器和编辑器有什么作用
    Beyond Compare切换到浏览模式的步骤
    spfa优化板子
    Tournament ZOJ
    My Brute HDU
    网络流想法随记
  • 原文地址:https://www.cnblogs.com/yuchao123/p/10689220.html
Copyright © 2011-2022 走看看