android笔记_android开发笔记 - CSDN
精华内容
参与话题
  • Android学习之路笔记

    千次阅读 2018-03-08 12:49:10
    最近是看了下大二上学期的时候学习Android的一些笔记资料,觉得以前是写的还有需要改进的地方,所以准备再重新整理整理发出来。学习Android的时候,是采用的视频+文档结合的方式。书呢看的是:郭大神的《第一行代码...

    这里写图片描述

    最近是看了下大二上学期的时候学习Android的一些笔记资料,觉得以前是写的还有需要改进的地方,所以准备再重新整理整理发出来。学习Android的时候,是采用的视频+文档结合的方式。书呢看的是:郭大神的《第一行代码》。所以本篇笔记还是按照郭大神的目录来进行记录的。

    第一章:了解全貌——Android王国简介

    1、Android的四层架构:Linux内核层、系统运行库层、应用框架层和应用层
    2、Android的四大组件:活动(Activity)、服务(Service)、广播接收器(Broadcast Receiver)、内容提供器(Content Provider)
    3 、使用res目录下的资源的两种方式

    例如:
        使用Res/values/string.xml文件,内容如下   
    <resources>
        <string name="app_name>HrlloWorld</string>
    </resources>
    在代码中采用R.string.app_name获得HelloWorld的引用
    在XML中通过@string/app_name获得引用
    

    4、app下的build.grade文件分析

    apply plugin: 'com.android.application'   应用的插件,有两种值可以选,com.android.application 表示这是一个应用程序模块,com.android.library表示这是一个库模块。
                                             应用程序模块和库模块的最大区别是应用程序模块是可以直接运行的,而库模块只能作为代码库依赖于其他应用程序模块来运行。
    android
       compileSdkVersion 25   项目编译的版本
       buildToolsVersion "25.0.2"   项目构建工具的版本
       defaultConfig {  对项目的更多细节进行配置
           applicationId "com.example.dimple.alertdialog"   指定项目的包名
           minSdkVersion 25    指定项目最低兼容的安卓版本
           targetSdkVersion 25    表示Android25上已经做了充分的测试,
           versionCode 1      指定项目的版本号
           versionName "1.0"    指定项目的版本名
           testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
       }
       buildTypes { 用于指定安装文件的相关配置
           release {
               minifyEnabled false   表示是否对项目进行代码混淆
               proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'  指定混淆的时候使用的规则文件
           }
       }
    }
    ​
    dependencies {  指定当前项目的依赖关系,Android中一共有三种依赖方式:本地依赖、库依赖、远程依赖。
                    本地依赖可以对本地的jar包或者目录添加依赖关系,库依赖可以对项目中的库模块进行添加依赖关系。
                    远程依赖可以对jcenter库上的开源项目添加依赖关系。
       compile fileTree(dir: 'libs', include: ['*.jar'])   本地依赖声明,表示将lib目录下的所有的jar文件添加到项目的构建路径中
       androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
           exclude group: 'com.android.support', module: 'support-annotations'
       })
       compile 'com.android.support:appcompat-v7:25.3.0'   标准的远程依赖库格式,其中“com.android.support”是域名部分,用于和其他公司的库作区分。
                                                            “appcompat-v7”是组名称,用于和同一个公司的不同的库作区分。“25.3.0”是版本号,用于和同一个库的不同版本作区分。
       compile 'com.android.support.constraint:constraint-layout:1.0.1'
       testCompile 'junit:junit:4.12'
    }
    

    第二章 先从看得到的入手——探究活动

    1、Genenate Layout File 是表示自动为Activity创建一个布局,Launcher Activity表示将当前活动设置为主活动。

    2、配置主活动的方法:在Manifest中的Activity标签中添加标签,并在这个标签中添加

    <action android:name="android.intent.action.MAIN"/>
    <category android:name-"android.intent.category.LAUNCHER"/>  
    

    3、在活动中使用Menu

    在res中新建Menu文件夹,创建XML文件,然后在相应的Java代码中重写onCreateOptionMenu()和onOptionItemSelect()方法。

    在onCreateOptionMenu():  
    public boolean onCreateOptionMenu()
    {
       getMenuInflater().inflater(R.menu.main,menu);
       return true;
    }  
    

    onOptionItemSelect()用于响应用户的事件。在此函数中,可以通过:item.getItemId判断点击的是哪一个菜单项。

    4、销毁一个活动使用finish()函数,效果和按下back键是一样的

    5、使用Intent

    Intent是Android程序中各组件之间进行交互的主要方式,它不仅可以指明当前组件想要执行的动作,还可以在不同的组件之间进行数据的传递。Intent一般可以用于启动活动,启动服务,以及发送广播等场景。

    Intent有多个构造函数:Intent(Context packageContext,Class

    6、Intent向上一个活动传递数据。

    使用startActivityForResult()方法在A中来启动Activity B;第一个参数是Intent,第二个参数是请求码,用于在回调之后来判断数据的来源。

    在B中Intent中putExtra()来返回要传递的数据。

    同时调用setResult()方法,第一个参数是要上一个活动A传递的处理结果,一般只使用RESULT_OK或RESULT_CANCELED两个值,第二个参数价将带有数据的Intent返回。

    在A中重写onActivityResult()方法,此方法有三个参数,第一个参数requestCode是我们在A中使用startActivityForResult()方法传入的,第二个参数是resultCode是在B中返回数据的时候传入的setResult方法中的结果码。第三个参数是传入的数据。

    一般是重写back键按下之后回调的方法:onBackPressed();

    7、活动的生命周期

    • 当活动被首次创建的时候:
      会依次调用:    onCreate()方法、onStart()方法、onResume方法。
    • 当从当前的活动跳转到另一个界面的时候(当前活动不可见)
      会依次调用:      onPause()方法、onStop()方法
    • 当从其他活动再跳转回来的时候
      会依次调用:     onRestart()方法、onStart()方法、onResume()方法
    • 当从当前活动跳转自另一个活动的时候(当前活动可见)
      会依次调用:    onPause()方法
    • 当从这个活动跳转会主活动的时候
      会依次调用:    onResume()方法
    • 结束当前活动的时候
      会依次调用:     onDestory()方法
      # 第三章 常用控件的使用方法

    ListView的使用

    listView 的简单用法

            首先,需要在布局中加入ListView控件,然后需要定义适配器(一般是ArrayAdapter)
    ArrayAdapteradapter=new ArrayAdapter(
       context,resourse,data);
    listView.setAdapter(adapter);

    ListView之自定义适配器

        首先先创建一个类,这个类中包含了需要进行自定义适配器需要用到的相关资源文件,此类为JAVABean。
    此外,还需要一个适配器,适配器继承自ArrayAdapter<>并泛型为定义的类。在此适配器中,重写getView()方法。

       `     
        /***  
        * 自定义适配器,继承自ArrayAdapter,并将泛型指定为Fruit类  
        */  
        class MyAdapter extends ArrayAdapter<Fruit>{  
           /**  
            *  
            * @param context  
            * @param resource  
            * @param objects  
            */  
           private  int Resource;  
           public MyAdapter(@NonNull Context context, @LayoutRes int resource, @NonNull List<Fruit> objects) {  
               super(context, resource, objects);  
               Resource=resource;  
           }  
        ​  
           @NonNull  
           @Override  
           public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {  
               View view;  
               ViewHolder viewHolder;  
               Fruit fruit=getItem(position);    
               if (convertView==null){  
                   view= LayoutInflater.from(getContext()).inflate(Resource,parent,false);  
                   viewHolder-new ViewHolder();  
                   viewHolder.ImageView imageView=view.findViewById(R.id.imageView);  
                   viewHolder.TextView textView=view.findViewById(R.id.textView);  
                   view.setTag(viewHolder);//将ViewHolder存储在View中
               }else{  
                   view=convertView;  
                   viewHolder=(ViewHolder)getTag();//重新获取ViewHolder  
               }  
               imageView.setImageResource(fruit.getFruitImage());  
               textView.setText(fruit.getFruitName());  
               return view;  
           }  
           class ViewHolder(){  
               ImageView fruitImage;  
               TextView fruitName;  
               
           }  `
    

    其中getItem()方法是每个子项滚动到屏幕类的时候被调用。
        convertView将之前的项目进行缓存。
    新建一个内部类ViewHolder,用于对实例对象进行缓存,把控件的实例都存放在viewHolder中,然后调用View的setTag()方法,将ViewHolder对象保存在View中,当convertView不为null的时候,调用View中的getTag()方法,将ViewHolder取出。这样系统每次就不用通过findViewById()来获取控件实例。
        点击事件需要设置监听

       @Override
       public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
          Fruit fruit=fruitList.get(i);
           Toast.makeText(getApplicationContext(),"position"+i+fruit.getFruitName(),Toast.LENGTH_LONG).show();
       }
    

    RecyclerView使用

    由于是新增的部件,所以需要添加依赖包

    compile 'com.android.support:recyclerview-v7:26.+'  //此处需要注意的是V7:后的,是appcompat后面的版本号

          initData();//初始化集合List中的数据
           RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
           FruitAdapter adapter = new FruitAdapter(fruitList);
           /**
            * 这里用于指定RecyclerView的布局方式
            */
           LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
           recyclerView.setLayoutManager(linearLayoutManager);
           recyclerView.setAdapter(adapter);
    public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder>{
       private List<Fruit>mFruitList;
    
           /**
            * 构造函数用于将要展示的数据传入,并赋值给一个全局变量mFruitList。
            * @param mFruitList
            */
           public FruitAdapter(List<Fruit> mFruitList) {
               this.mFruitList = mFruitList;
           }
        ​
           /**
            * 首先定义了一个内部类ViewHolder,ViewHolder要继承自RecyclerView.ViewHolder,然后ViewHolder的构造函数要传入一个view参数
            * 这个参数通常就是RecyclerView子项最外层的布局。
            */
           static class ViewHolder extends RecyclerView.ViewHolder{
               ImageView fruitImage;
               private View fruitView;//设置view点击事件  添加此变量来保存子项最外层的布局的实例
               TextView fruitName;
               public ViewHolder(View view) {
                   super(view);
                   fruitView=view;//获取View
                   fruitImage=view.findViewById(R.id.imageView);
                   fruitName=view.findViewById(R.id.textView);
        ​
               }
           }
        ​
           /**
            * onCreateViewHolder()是用于创建ViewHolder实例的,在这个方法中,将布局加载到ViewHolder的实例中,然后将ViewHolder实例返回
            * @param parent
            * @param viewType
            * @return
            */
           @Override
           public FruitAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
               View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item,parent,false);
        ​
               final ViewHolder holder=new ViewHolder(view);
               /**
                * ViewHolder设置点击事件
                */
               holder.fruitView.setOnClickListener(new View.OnClickListener() {
                   @Override
                   public void onClick(View view) {
                       /*
                       通过ViewHolder的getAdapterPosition获得position
                       然后可以通过该位置在List中获取实例
                        */
                       int position =holder.getAdapterPosition();
                       Fruit fruit=mFruitList.get(position);
                       Toast.makeText(view.getContext(),"this is "+ fruit.getFruitName(),Toast.LENGTH_LONG).show();
                   }
               });
               return holder;
           }
        ​
           /**
            * 用于对RecyclerView子项的数据进行赋值,当每个子项被滚动到屏幕内的时候被调用
            * @param holder
            * @param position
            */
           @Override
           public void onBindViewHolder(FruitAdapter.ViewHolder holder, int position) {
               Fruit fruit=mFruitList.get(position);
               holder.fruitImage.setImageResource(fruit.getFruitImage());
               holder.fruitName.setText(fruit.getFruitName());
           }
        ​
           /**
            * 返回当前要加载的数据源的长度
            * @return
            */
           @Override
           public int getItemCount() {
               return mFruitList.size();
           }
        }`
    

    瀑布流使用: StaggeredGridLayoutManager  设置瀑布流的布局方式

    如果需要设置为横向滑动的话就需要在MainActivity中的LinearLayoutManager设置方向

     linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);

    使用步骤:

    获取RecyclerView实例——设置layoutManager布局对象——绑定适配器
    创建JavaBean类
    创建适配器——继承自《RecyclerView.Adapter

    第四章 碎片

    碎片的静态加载

    在MainActivity的布局文件中添加的使用

    <fragment  
           android:id="@+id/id_fragment_title"  
           android:name="com.zhy.zhy_fragments.TitleFragment"  
           android:layout_width="match_parent"  
           android:layout_height="45dp" />  
    

    在TitleFragment的布局文件和JAVA文件中进行操作
    在java文件中重写onCreateView方法,注意要继承只V4包的Fragment

    碎片的动态加载

    在MainActivity的布局文件中声明一个区域作为碎片出现的位置 。
    找MainActivity的JAVA文件中首先设置默认的显示的Fragment

    prvate void setDefaultFragment(){
       FragmentManager fm =getFragmentManager();
       FragmentTransaction transaction = fm.beginTransaction();
       FragmentOne one=new FragmentOne();
       transaction.replace(R.id.mainactivity_fragment,one);
       transaction.commit();
    }
    

    Fragment常用的API:

    Fragment常用的三个类

    要用于定义Fragment。

    • android.app.FragmentManager主要用于在Activity中操作Fragment。
    • android.app.FragmentTransaction保证一系列Fragment操作的原子性。

    获取FragmentManager的方式
    - getFragmentManager()  //在V4包中,getSupportFragmentManager()

    主要的操作中都是FragmentTransaction的方法
        FragmentManager fm =getSupportFragmentManager();
        FragmentTransaction transaction = fm.beginTransaction();//开启一个事务
        transaction.add(); //向Activity中添加一个Fragment
        transaction.remove();//从Activity中移除一个Fragment
        transaction.replace();//使用另一个Fragment替换掉当前的Fragment,实际上是remove()和add()的合体
        transaction.show();//显示之前隐藏的Fragment
        transaction.hide();//隐藏当前的Fragment,仅仅设置为隐藏,并不会销毁
        transaction.commit();//提交一个事务

    注:如果希望保留用户在当前fragment的数据,就使用hide()和show()组合,这样不会销毁当前的Fragment
            如果不希望保留用户当前在Fragment的数据,就使用remove()和add()组合或者直接使用replace(),这样就会销毁当前的Fragment,再进去的时候就会重新加载
            如果使用replace的话,当程序已经不在当前的界面的时候,在其他界面按Back键的时候,将不会返回到这个界面,直接退出
            想要保留这个fragment的话,就需要将它添加到回退栈中: transaction.addToBackStack();
    参考博客

    第五章 广播

    1、广播的两种类型

    • 标准广播  广播发出后,所有的广播接收器会在同一时间接收到这条广播。效率较高,无法截断。
    • 有序广播  广播发出后,同一时刻只有一个广播接收器能够接收到这条广播,并且优先级高的可以先接收到这条广播,并且前面的广播接收器可以截断广播。

    2、注册广播的两种方式

        在代码中注册——动态注册——在程序关闭之后就不能再接收到广播
        在AndroidManifest中注册——静态注册——与程序是否关闭无关

    3、创建广播接收器的方法

    新建一个类,继承自BroadcastReceiver,并重写父类的onReceive()方法。
    这样,当有广播到来的时候,onReceive()方法就会得到调用。

    4、动态注册广播的方法

    创建IntentInfilter的实例,添加一个action

    IntentInfilter intentInfliter =new IntentInfliter();//创建IntentFilter实例  
    intentInfilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");//为这个IntentFilter添加action  
    registerReceiver(networkChageReceiver,interFilter);//动态注册广播,这样networkChangeReceiver就会接收到所有值为android.net.conn.CONNECTIVITY_CHANGE的广播   
    

    动态注册的广播需要取消注册,在onDestory中调用unRegisterReceiver()方法来实现的。

    5、静态注册广播的方法

    使用android Studio的快捷键创建一个广播接收器,点击包名——New——Other——Broadcast Receiver,Exported表示是否允许广播接收器接收本程序以外的广播,Enable表示是否启用这个广播。

    (静态注册的广播接收器必须要在AndroidManifest中注册才能使用,使用Android Studio创建的广播接收器已经在AndroidManifest中注册了)
    注册方式信息如下:

           <receiver
               android:name=".MyReceiver"
               android:enabled="true"//是否启用该广播接收器
               android:exported="true">//是否允许接受本程序之外的广播
               <intent-filter  android:priority="100">//priority是设置广播的优先级,优先级越高系统响应越快
                   <action android:name="android.intent.action.BATTERY_LOW"/>//当系统低电量的时候就会发出这个广播
               </intent-filter>
           </receiver>
       </application>
    
    在<intent-filter>标签中添加相应的Action标签
    

    注意某些操作需要用到权限,需要在Manifest中添加权限。

    此外,在onReceive中不能添加太多的逻辑以及耗时操作,在广播接收器中是不允许多开线程的,当此方法运行了太长时间而没有结束,程序会报错。

    发送动态广播的方法:

    Intent intent=new Intent("android.net.conn.CONNECTIVITY_CHANGE");
    sendBroadcast(intent);
    

    6、自定义广播

    创建一个自定义的广播接收器继承自BroadcastReceicer,并重写onReceive()方法。
    然后使用Intent发送广播。

    • 有序广播
      在Manifest中的Broadcast标签的Intent-filter中设置优先级属性priority
      发送广播的时候与标准广播不同
      sendOrderBroadcast(intent,null)//第一个是Intent实例,第二个是与权限相关的字符串,这里传入null
    • 截断广播
      abortBroadcast();//在广播接收器中调用这个方法就可以截断广播

    7、本地广播

        本地广播的出现是为了解决广播在整个系统中运行中的安全性的问题,全局广播会被其他程序所截获,造成信息泄露。
        本地广播的用法
    主要是使用一个LocalBroadcastManager来对广播进行管理,并提供了发送广播和和注册广播的方法。

     localBroadcastManager=LocalBroadcastManager.getInstance(getApplicationContext());
           Button button= (Button) findViewById(R.id.button);
           button.setOnClickListener(new View.OnClickListener() {
               @Override
               public void onClick(View v) {
                   Intent intent=new Intent("com.example.dimple.mytest.MYMY");
                   localBroadcastManager.sendBroadcast(intent);
               }
           });
           IntentFilter intentFilter=new IntentFilter();
           intentFilter.addAction("com.example.dimple.mytest.MYMY");
           localBroadcastManager.registerReceiver(new MyReceiver(),intentFilter);
    

    本地广播只能通过动态注册。

    通过LocalBroadcastMaager的getInstance()方法得到实例。
    然后注册广播的时候就调用LocalBroadcastManager()的registerRecriver()方法.
    在发送广播的时候就调用LocalBroadcastManager的sendBroadcastManager()方法。

    第六章 存储

    1、使用SharedPreferences

    SharedPreferences是采用键值对的方式来存储数据的。
    要使用SharedPreferences需要首先获得SharedPreferences对象。获取该对象的方式有:
    - Context类中的getSharedPreferences()方法,接收两个参数,第一个参数是文件的名称,第二个参数指定操作模式MODE,目前只能选择MODE_PRIVATE。
    - Activity类中的getPreferences()方法,和getSharePreferences差不多,区别是使用getPreferences会使用当前的类名作为文件名。
    - PrederencesManager类中的getDefaultSharedPreferences()方法 ,这是一个静态方法,接收一个context参数,会自动将当前的应用程序的包名作为前缀来命名SharePreferences文件

    使用步骤
    调用sharedPreferences对象的editor()方法来获得一个 sharedPerferences.Editor()对象
    向sharedPerferences.Editor()对象添加数据。调用editor的putString()等些列方法
    调用editor的apply()方法提交数据。

    读取SharedPreferences的方法

    获取SharedPreferences对象,通过getString()系列方法得到数据。注意这里有两个参数,第一个是要读取的数据的键,第二个参数是没有找到这个数据返回的值。

    2、使用SQLite数据库进行存储

    android中为了更好的管理数据库,提供了一个SQLiteOpenHelper的帮助类(抽象类),需要实现SQLiteOpenHelper抽象方法中的抽象方法onCreate()(在数据库被创建的时候会调用),onUpgrade()(在数据库版本被升级的时候被调用)

    获取实例的方法:(都可以打开或者创建数据库)
    getReadableDatebase()只能是通过只读的方式来打开数据库。
    getWritableDatebase()使用读写的方式打开数据库。

    使用方法:
    新建一个JAVA类继承自SQLiteOpenHelper,实现两个抽象方法onCreate()和onUpgrade(),创建构造器(使用参数较少的那一个构造器),其参数有

    Context context, String name, SQLiteDatabase.CursorFactory factory, int version
    

    /*
    第一个参数是context上下文
    第二个参数是数据库名
    第三个参数允许在查询的时候返回一个自定义的Cursor,一般为null
    第四个参数是当前数据库的版本号,可用于对数据库的更新操作
    */

    构建出SQLiteOpenHelper实例(new)以后,调用getReadableDatebase()或者getWritableDatebase()就可以创建数据库了。
    创建的数据库的名字一般放在 /data/data//datebase目录下。

    配置adb 在安卓SDK的目录下有一个platform-tools文件夹,将这个文件夹配置到系统的环境变量中,使用adb shell进入控制台终端

    使用sqlite3 +数据库名称 打开数据库
    使用.table 查看数据库中的表、
    使用 .schema 查看建表语句

    3、向SQLite数据库中添加数据
    调用SQLiteOpenHelper的getReadableDatebase()或者getWritableDatebase()创建数据库后会返回一个SQLiteDatabase对象,借助这个对象就可以对数据库进行CRUD操作
    添加数据
        SQLiteDatabase提供一个insert()方法用于添加数据。这个方法有三个参数。第一个参数是数据库表名称,第二个是用于指定在未添加数据的情况下给某些数据项自动赋值为null,第三个参数是ContentValues对象,它提供一系列的put()方法重载,用于向contentValues添加数据。使用此方法的时候需要创建ContentValues对象。

    sqLiteDatabase.insert("Book",null,contentValues);//插入信息到Book
    

    更新数据
        SQLiteDatabase提供一个update()的方法,第一个参数是表名,第二个参数是ContentValues对象,第三四个参数用于约定更新某一行或者某几行的数据。
        

        sqLiteDatabase.update("Book",contentValues,"id=?",new String[]{"1"});//更新id为1的书的信息
        第三个参数对应的是SQL的where语句,第四个提供约束的具体信息。
    

    删除数据

        SQLiteDatabase提供一个delete()的方法,第一个参数是表名,第二三个参数用于约定删除某一行或者某几行的数据。

     sqLiteDatabase.delete("Book","pages>?",new String[]{"500"});//删除页数超过500页的书的信息  
    

    查询数据

    query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit)方法各参数的含义:
    

     
    - table:表名。相当于select语句from关键字后面的部分。如果是多表联合查询,可以用逗号将两个表名分开。
     
    - columns:要查询出来的列名。相当于select语句select关键字后面的部分。
     
    - selection:查询条件子句,相当于select语句where关键字后面的部分,在条件子句允许使用占位符“?”
     
    - selectionArgs:对应于selection语句中占位符的值,值在数组中的位置与占位符在语句中的位置必须一致,否则就会有异常。
     
    - groupBy:相当于select语句group by关键字后面的部分
     
    - having:相当于select语句having关键字后面的部分
     
    - orderBy:相当于select语句order by关键字后面的部分,如:personid desc, age asc;
     
    - limit:指定偏移量和获取的记录数,相当于select语句limit关键字后面的部分。

                       sqLiteDatabase=mySqlite.getWritableDatabase();
                       Cursor cursor=sqLiteDatabase.query("Book",null,null,null,null,null,null);//查询完毕后得到一个游标Cursor对象,通过这个对象去访问数据
                       if (cursor.moveToFirst()){//将游标移动到第一行的位置
                           do{//接下来是循环
                               //在这个循环中可以通过Cursor的getColumnIndex()方法获取到某一行的索引。将这个索引传入相应的取值方法中就可以得到相应的数据了。
        ​
                               String name=cursor.getString(cursor.getColumnIndex("name"));
                               String author =cursor.getString(cursor.getColumnIndex("author"));
                               int pages=cursor.getInt(cursor.getColumnIndex("pages"));
                               double price=cursor.getDouble(cursor.getColumnIndex("price"));
                               builder.append("name\n").append(name).append("author\n").append(author).append("pages\n").append(pages).append("price\n").append(price);
                           }while (cursor.moveToNext());
                           textView.setText(builder);
                       }
    

    4、使用LitePal操作数据库

    配置过程
        编辑app/build.gradle文件,在dependencies闭包中加入

       compile 'org.litepal.android:core:1.3.2'
    

    然后在app/src/main目录新建一个assets目录,在此目录下创建一个litepal.xml文件

    <litepal>  
        <!--dbname标签用于指定数据库名,version标签用于指定数据库版本号,list标签用于指定所有的映射模型-->  
        <dbname value="BookStore"></dbname>
        <version value ="2"></version>
        <list>
            <mapping class="com.example.dimple.sharedpreferencestest.Book"></mapping>
            <mapping class="com.example.dimple.sharedpreferencestest.Category"></mapping>
        </list>
    </litepal>
    

    最后需要在AndroidManifest中将项目的application配置为

       <application
           android:name="org.litepal.LitePalApplication"
           android:allowBackup="true"
           android:icon="@mipmap/ic_launcher"
    

    创建数据库:
        使用面向对象的思想,定义一个Book类JavaBean类。
        将关系模型添加到映射模型列表中

    <mapping class="com.example.dimple.sharedpreferencestest.Book"></mapping>
    

    注:不管需要多少关系模型,注意要使用完整的类名,不管需要多少模型类映射,都需要用同样的方式在标签下配置。

    在代码中使用Connector.getDatabase();创建数据库。

    升级版本号,就可以直接修改litepal.xml中的version即可。此升级不会删除数据库。

    添加数据
        需要将JavaBean类继承自DataSupport类。
        在java代码中,直接new一个JavaBean类的对象出来,然后调用set系列方法,最后调用DataSupport父类传下来的save()方法即可。

    更新数据
    直接new一个JavaBean对象出来,调用要修该的数据项的set函数,然后updataAll();  此方法可以设置约束条件

     book.updateAll("name=?","the da vinvi code ");//修改所有name=the da vinvi code的数据项。
    

    删除数据

     DataSupport.deleteAll(Book.class,"price>?","17");
    第一个参数是指定表,后面的参数是指定参数的数据项的属性。
    

    查询数据
    注:     
    for (Book book:bookList)的意思是循环bookList集合,每次取得的实例就给Book book;

    List bookList=DataSupport.findAll(Book.class);  
    findAll()返回的是一个List集合。

    常用的查询API
    - 查询第一条数据

      Book book =DataSupport.findFirst(Book.class);  
    
    • 查询最后一条数据

      Book book =DataSupport.findLast(Book.class);  
      
    • select()方法可以指定查询那几列的数据。

      List<Book> bookList =DataSupport.select("name","pages").find(Book.class);
      
    • where()方法可以指定查询的约束条件

       List<Book> bookList =DataSupport.where("name=?","bianxiaofeng").find(Book.class);  
      
    • order()方法可以指定结果的排序方式

      List<Book> bookList =DataSupport.order("pages desc").find(Book.class);
      
    • limit()方法可以指定结果的数量

      List<Book> bookList =DataSupport.limit(3).find(Book.class);
      

    还可以对所有的方法进行连缀组合操作。

    第七章 内容提供器

    1、内容提供器主要在不同的应用程序之间实现数据共享的功能。使用内容提供器是Android跨程序共享数据的标准方式。

    2、运行时权限

        权限分为普通权限和危险权限。危险权限分为9组24个。每一个危险权限都属于一个权限组,一旦用户同意了某个权限组的一个权限,则对应的权限组都可以被获得权限。
        
    步骤:
    第一步需要判断用户是不是已经授权了。借助的是ContextCompat.setSelfPermission()方法。此方法接收两个参数:第一个是Context上下文,第二个是具体的权限名。
    Manifest.permission.“`。使用方法的返回值和PackageManager.PERMISSION_GEANTED作比较,相等就表示已经授权。不相等就表示没有授权。

    如果授权的话就执行具体的逻辑。如果不等的话就说明还没有得到用户的权限的同意,这个时候需要申请用户的权限。

    调用ActivityCompat.requestPermission()方法来向用户申请权限。requrestPermission接受三个参数,第一个参数是要求的Activity实例,第二个参数是String数组,这里需要把要申请的权限名写在里面,第三个是请求码,需要唯一。在这个方法中判断是否得到授权。

    //申请权限
    if (ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission
                           .CALL_PHONE)!=PackageManager.PERMISSION_GRANTED){
                       ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest
                               .permission.CALL_PHONE},1);
                   }else {
                      //do something else
                   }
    @Override
       public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                              @NonNull int[] grantResults) {
               switch (requestCode){
                   case 1:
                       if (grantResults[0]==PackageManager.PERMISSION_GRANTED){
                           //do something else.
                       }else{
                           Toast.makeText(MainActivity.this,"failed!",Toast.LENGTH_LONG).show();
                       }
               }
       }
    

    3、contentResolver的基本用法

    对于一个应用程序来说,如果访问内容提供器中的共享的数据,就一定要借助ContentResolver类。可以通过getContentReslover来获取该类的实例。

    使用inset()用于添加数据。update()用于更新数据。delete()用户删除数据。queny()用于查询数据。ContentReslover的增删查改需要接受Uri对象作为参数。

    和数据库的操作一样是使用ContentValues作为中转传数据。调用CRUD函数进行操作。

    第八章 运用手机多媒体

    1、使用通知Notification

    使用通知的步骤
    首先需要一个NotificationManager来对通过通知进行管理,可以调用Context的getSystemService()方法来获取到。
    getSystemService()方法接受一个字符串参数用于确定获取系统的哪一个服务。这里传入Context.NOTIFICATION_SERVICE即可。

    NotificationManger manager=(NitificationManager)getSystemSerice(Context.NOTIFICATION_SERVICE);
    

    接下来需要一个Builder构造器来创建Notification对象(为了实现兼容,使用v4包的NotificationCompat类)

    Notification notification =new NotificationCompat.Builer(context);  
    

    然后调用一系列的set方法对这个实体类进行设置。最后调用manager的notify()方法,该方法接收两个参数,第一个参数是Notification的id,第二个参数是Notification的类。
    以上功能实现后就可以发送通知了,不过通知不可点击。如果需要点击需要PendingIntent

    注:PendingIntent和Intent的异同点:

    • 都可以指明一个意图,都可以用于启动活动,服务,以及发送广播。

    • Intent倾向于立即去执行某个动作,PendingIntent更加倾向在合适的时机去执行某个动作。

    pendingIntent的使用方法:
    使用静态方法获得PendingIntent的实例,getActivity()、getBroadcast()、getService()。

    四个参数:content,0,Intent对象、0

    Intent intent=new Intent(MainActivity.this,nextActivity.class);
    PendingIntent pi=PendingIntent.getActivity(MainActivity.this,0,intent,0);
    

    不能这个通知写在OnClickListener的匿名内部类

    2、调用摄像头

    private void camera() {
           /**
            * 首先创建了一个File对象,用于存放摄像头拍下的图片,这里将图像命名为outputImage.jpg,并将它存放在手机的关联目录下、
            * 接着进行一个判断,如果设备系统的版本低于7.0 的话就,就调用Uri的fromFile()方法将File转化为Uri对象,这个Uri对象标识着outputImage这张图片的真实路径,否则
            * 就调用FileProvider的geUriForFile()将File转化成一个封装过的Uri对象。
            */
           File outputImage=new File(Environment.getExternalStorageDirectory(),"output_image.jpg");
           try{
               if (outputImage.exists()) {
                   outputImage.delete();
               }
               outputImage.createNewFile();
           } catch (IOException e) {
               e.printStackTrace();
           }
           if (Build.VERSION.SDK_INT>=24){
               imageUri= FileProvider.getUriForFile(MainActivity.this,"com.example.dimple.test619.fileProvider",outputImage);
           }else{
               imageUri=Uri.fromFile(outputImage);
           }
           Intent intent=new Intent("android.media.action.IMAGE_CAPTURE");
           intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);//填入指定的文件输出地址
           startActivityForResult(intent,TAKE_PHOTO);
       }
    @Override
       protected void onActivityResult(int requestCode, int resultCode, Intent data) {
           switch (requestCode) {
               case TAKE_PHOTO: {
                   if (resultCode == RESULT_OK) {
                       try{
                           Bitmap bitmap= BitmapFactory.decodeStream(getContentResolver()//将图片解析为bitmap对象
                                   .openInputStream(imageUri));
                           picture.setImageBitmap(bitmap);
                       } catch (FileNotFoundException e) {
                           e.printStackTrace();
                       }
    ​
                   }
               }
               break;
               default:
                   break;
           }
    

    因为用到了ContentProvider,所以需要在Manifest中注册

    <provider
                android:authorities="com.example.dimple.test619.fileProvider"
                android:name="android.support.v4.content.FileProvider"
               android:exported="false"
               android:grantUriPermissions="true">
               <meta-data   //指定Uri的共享路径
                   android:name="android.support.FILE_PROVIDER_PATHS"
                   android:resource="@xml/file_paths"/>
            </provider>
        </application>
    ​
    </manifest>
    

    新建XML文件

        <?xml version ="1.0" encoding="utf-8" ?>
            <path xmlns:android="http://schemas.android.com/apk/res/android">
            <external-path name="my_images" path=""/>
        </path>  
    

    3、播放音频

    在Android中播放音频文件一般都是使用MediaPayer来实现的,它对多种格式的音频文件提供了非常全面的控制方法,使得音频播放比较简单。

    方法名         功能描述          备注    
    setDataSource()     设置要播放的文件的地址     
    prepare()       在开始播放之前调用这个方法完成准备工作     
    start()     开始播放视频      
    pause()     暂停播放音频      
    reset()     将Mediaplayer对象重置为刚开始创建的状态       
    seekTo()        从指定的位置开始播放音频        
    stop()      停止播放音频      
    release()       释放掉与MediaPlyer相关的资源     
    isPlaying()     判断当前MediaPlayer是否在播放        
    getDuration()    获取之路的音频文件的时长   
    

    4、播放视频

    方法名            功能描述       备注    
    setVideoPat()   设置要播放的视频文件的地址           
    start()     开始或继续播放视频       
    pause()     暂停播放视频      
    resume()        将视频从头播放     
    isPlaying()     是否正在播放      
    getDuration()       获取时长    
    seekTo()        从指定的位置开始播放  
    XML中包含VideoView。
    通过VideoView来进行操作。
    

    第九章 使用网络技术

    1、WebView 的用法

    获取WebView的实例,通过getSetting()方法对浏览的相关属性进行设置。调用setJavaScriptEnabled()方法来让WebView支持JavaScript脚本。调用wenViewClient()方法。是希望网页依然在本程序中,不然就会跳转出去。

    2、使用HTTP协议访问网络

    首先开启一个子线程,在子线程中进行网络数据请求操作,获取HttpRULConnection实例。

    URL url=new URL("https://www.baidu.com");
    HttpURLConnection connection==(HttpURLConnection)url.openConnection();
    connection.setConnectionTimeOut(8000);//设置链接超时
    connection.setReadTimeOut(8000);//设置读取超时
    

    之后再调用getInputStream()方法获取到服务器返回的流,然后进行流读取。

    ImputStream in=connection.getInputStream();
    //下面进行流读取
    BufferedReader reader=new BufferedReader(new InputStreamReader(in));
    String line;
    StringBuilder builder=new StringBuilder();
    while((line=reader.readerLine())!=null){
      builder.append(line);
    }
    
    最后关闭链接
    connection.disconnect();
    

    3、使用OkHttp

    在app/build.grade中dependencies中添加如下内容:

    compile 'com.squareup.okhttp3:okhttp:3.4.1'
    

    具体使用步骤:
    创建一个OkHttpClient实例

    OkHttpClient client=new OkHttpClient();  
    

    接下来如果需要发起一条Http请求,需要创建一个Request对象

    Request request=new Request.Builder().build();  
    

    以上代码创建了一个空的Request对象,没有什么实际作用,在build()方法之前加入很多连缀来丰富这个request对象,可以使用uri()方法来设置目标网络地址。

    之后调用OkHttpClient的newCall()方法来创建一个Call对象,并调用它的execute()方法来发送请求并获得服务器的数据。

    Response response=client.newCall(request).execute();
    

    其中Resopnse就是服务器返回的数据了,以下方法可以得到具体的内容

    String responseData=response.body().string();
    

    发送数据:

    首先需要构建出一个RequestBody对象来存放待提交的数据。

    ResquestBody requestBody=new FormBody.Builder().add("username","admin").add("password","123456").build();
    

    接下来就和Get请求一样了,调用execute()方法来获得服务器返回的数据。

    4、解析JOSN数据

    http://mobileapi.72g.com/index.php?tp=andv4/quan&op=qinfo

    5、解析Json数据

    首先配置服务器:电脑端访问网址为127.0.0.1 模拟器访问端网址:10.0.2.2

    使用JsonObject:
    首先将从服务器中的数据放在JSONArray中,然后循环遍历这个Json数组,从中取出的每一个元素都是JSONObject对象,调用getString()方法就可以取出数据。

                   JSONArray jsonArray=new JSONArray(response);
                       for (int i=0;i<jsonArray.length();i++){
                           JSONObject jsonObject=jsonArray.getJSONObject(i);
                           Log.d("TAG", "Data :"+jsonObject.getString("name")+jsonObject.getString("id")+jsonObject.getString("version"));
                       }
    

    使用Gson
    首先需要添加依赖

       compile 'com.google.code.gson:gson:2.8.1'
    

    Gson可以将一段Json格式的字符串自动映射成为一个对象,从而不需要我们编写代码进行解析。

    比如:一段json格式的数据如下
    {“name”:”Tom”,”age”:”20”}
    我们可以定义 一个Person类,并加入name和age两个字段。只需要简单的调用如下代码就可以将JSON数据自动解析成一个Person对象了。

    Gson gson=new Gson();
    Person person=gson.fromJson(jsonData,Person.class)  
    

    如果解析的是一段json数组就需要借助TypeToken将期望解析成的数据类型传入到fromJson中。

    Gson gson=new Gson();
     List<App>appList=gson.fromJson(response,new TypeToken<List<App>>(){}.getType());
    for (App app:appList){
      Log.d("TAG", "run: "+app.getId()+"\n"+app.getName()+"\n"+app.getVersion());
     }
    

    定义Okhttp工具类

    public class HttpUtility {
       public static void senOkHttpRequest(String address,okhttp3.Callback callback){
           OkHttpClient client=new OkHttpClient();
           Request request=new Request.Builder().url(address).build();
           client.newCall(request).enqueue(callback);
       }
    }
    ​
    

    在调用工具类的时候就这样写:

    HttpUtility.senOkHttpRequest("http://10.0.2.2/me.json", new okhttp3.Callback() {
               @Override
               public void onFailure(Call call, IOException e) {
    //                T网络请求失败"相关逻辑
               }
    ​
               @Override
               public void onResponse(Call call, Response response) throws IOException {
    //                网络请求成功相关逻辑
                   String responseData=response.body().string();
                   showResponse(responseData);
               }
           });
    

    第12章 Material Design

    1、ToolBar代替ActionBar

     需要在Manifest中设置主题为NoActionBar

    <android.support.v7.widget.Toolbar
           android:layout_width="match_parent"
           android:layout_height="?attr/actionBarSize"
           android:id="@+id/toolBar"
           android:background="@color/colorPrimary" />
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolBar);
           setSupportActionBar(toolbar);
    

    扩展:在ToolBar中添加其他控件
    新建menu文件夹,在其中添加Menu resourse file,创建一个xml文件。

    <item  
           android:id="@+id/delete"
           android:icon="@drawable/wujiaoxing"//指定按钮的图标
           android:title="@string/delete"//指定按钮的文字
           app:showAsAction="always" />//指定按钮的显示位置。always表示永远显示再ToolBar中,如果屏幕不够就不显示
                                       nerver表示永远显示再菜单项中,ifRoom表示屏幕空间足够的情况下就显示在ToolBar中,如果不够的话就显示在菜单项中。
    ​
    

    在MainActivity中重写onCreateOptionMenu方法显示出menu,使用onOptionsItemSelected()方法来响应点击事件。

    2、滑动菜单——DrawerLayout

    首先它是一个布局,在布局中只允许放入 两个直接控件,第一个子控件是主屏幕显示的内容,第二个子控件是滑动菜单栏显示的内容。

    使用

    <android.support.v4.widget.DrawerLayout></android.support.v4.widget.DrawerLayout>
    

    注意:

    第二个子控件需要设置android:layout_gravity=”“,需要告诉DrawerLayout菜单是再屏幕的右边还是左边

    android:layout_gravity="start"  
    

    使用ToolBar的最左边加入导航按钮。

    ActionBar actionBar=getSupportActionBar();//获取ActionBar的实例,这个实例的具体提现是由ToolBar来实现的。
    
    
           if (actionBar!=null){
               actionBar.setDisplayHomeAsUpEnabled(true);//显示导航键
               actionBar.setHomeAsUpIndicator(R.drawable.meiyuan);//设置导航键的图标。这个图标叫做HOMEAsUp
           }
    

    在onOptionsItemSelected()方法来对HomeAsUp按钮的点击事件,HomeAsUp的id是
    android.R.id.home

    然后调用DrawerLayout的openDrawert()方法将滑动菜单显示出来。

    3、NavigationView

    NavigationView是DesignSupport库中提供的一个控件。

    使用的时候需要添加闭包关系

       compile 'de.hdodenhof:circleimageview:2.1.0'
       compile 'com.android.support:design:26.0.0-alpha1'
    

    在使用Navigation之前,需要准备两个东西,menu和headLayout

    menu是在navigationView中显示菜单项的,headLayout是在NavigationView中显示头部布局的。

    头部布局中使用circleImage来设置圆形头像。

    设置完毕后在MainActivity中添加

    <android.support.design.widget.NavigationView
           android:id="@+id/nav_view"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:layout_gravity="start"
           app:headerLayout="@layout/nav_header"
           app:menu="@menu/nav_menu" />
    

    同时可以设置监听

    public boolean onNavigationItemSelected(@NonNull MenuItem item)
    

    4、悬浮按钮和可交互提示

    悬浮按钮

    添加FloatActionButton布局

           <android.support.design.widget.FloatingActionButton
               android:id="@+id/floatButton"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_gravity="bottom|end"
               app:elevation="8dp"设置悬浮高度
               android:layout_margin="10dp"
               android:src="@drawable/meiyuan" />
    

    setOnClickListener可以设置点击事件

    可交互提示:SnakeBar

       Snackbar.make(view,"Date Deleted",Snackbar.LENGTH_LONG)   //make方法创建了一个Snake对象,第一个 参数需要传入一个人View,只要是当前界面的任意一个View都可以,第二个参数是SnakeBar中显示的内容,第三个是显示的时长
                           .setAction("Un Do", new View.OnClickListener() {//调用setAction来设置一个动作,从而让SnakeBar不仅仅是一个提示,而是可以和用户进行交互的//第一个是按钮的名字,第二个是点击事件。
                               @Override
                               public void onClick(View view) {
                                   Toast.makeText(MainActivity.this, "Un Do Successed!", Toast.LENGTH_SHORT).show();
                               }
                           }).show();
    

    调用setAction来设置一个动作,从而让SnakeBar不仅仅是一个提示,而是可以和用户进行交互的//第一个是按钮的名字,第二个是点击事件。

    出现界面重叠,需要使用CoordinatorLayout来替换掉FrameLayout,它可以监听所有子控件的所有事件,从而自动做出合理的响应。

    5、卡片式布局

    添加依赖:

       compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
       compile 'com.android.support:cardview-v7:26.0.0-alpha1'
       compile 'com.github.bumptech.glide:glide:4.0.0-RC1'
    

    Glide是一个强大的图片加载库,它不仅可以加载本地图片,还可以加载网络图片,GIF图片,甚至是本地视频。

    具体操作见recyclerView,只是将recyclerView 的子项布局的外层布局改为CardView

    这种会将ToolBar遮盖,使用AppBarLayout
    使用AppBarLayout包裹ToolBar,同时指定RecyclerView的布局行为

               app:layout_behavior="@string/appbar_scrolling_view_behavior"
    

    同时还可以设置滑动隐藏
    在toolBar中加入

                   app:layout_scrollFlags="scroll|enterAlways|snap"
    

    scroll表示RecyclerView向上滑动的时候,ToolBar会一起向上隐藏,enterAlways表示向下滚动的时候,ToolBar会同步显示。snap表示还没有完全隐藏的时候,会自动向上向下偏移。

    6、下拉刷新

    SwipeRefreshLayout就是用于下拉刷新的核心类。使用《swipeRefreshLayout》包裹需要下拉刷新的部件。

    wipeRefresh.setColorSchemeResources(R.color.colorPrimary);
           swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
               @Override
               public void onRefresh() {
                   refreshFuite();
               }
           });  
    

    7、可折叠标题栏ColapsingToolbarLayout

    colapsing不能独立存在,在设计的时候就只能用作AppBarLayout的直接子布局。而AppBarLayout又必须是CoordinatorLayout的子布局

    DrawerLayout ——滑动菜单栏——只能拥有两个字节子布局(第一个是主屏幕的内容、第二个是滑动屏的内容)

    NavigationView——滑动菜单栏滑动屏布局(需要headLayout、和menu布局 (showAsAction))——需要Design Support库

    FloatActionButton——悬浮按钮

    SnakeBar——提示工具

    CoordinatorLayout——加强版的FrameLayout——监听子控件各种事件、自动做出合理的响应。防止控件重叠。

    CardView_FrameLayout——提供圆角和阴影效果(cardCornerRadius指定卡片的弧度,elevation指定卡片的高度)

    Glide——图片加载库

    AppBarLayout——解决FrameLayout中的默认位置为左上角造成的遮挡ToolBar——将ToolBar嵌套到AppBarLayout(    app:layout_scrollFlags=”scroll|snap|enterAlways”),然后给重叠的部件指定布局行为behaver

    SwipeRefreshLayout——下拉刷新——包裹需刷新的部件

    CollapsingToolbarLayout——可折叠标题栏——不能独立存在只能作为AppBarLayout的直接子布局、AppBarLayout必须是coordinatorLayout的子布局

    NestedScrollView——ScrollView——内部只能存在一个直接子布局

    总结

    以上就是我的Android学习过程中整理的一些东西,重新再整理了一遍,也算是重新学习了一次,在重新学习的过程中,还是发现有很多不足不周到的地方。温故而知新,自己还记录了很多笔记,趁现在还时间充裕,还会再好好温习一下。

    展开全文
  • 往sd卡写数据 ...android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> try { //得到sd卡路径 String str = Environment.getExternalStorageDirectory().getPath();  File file =
    往sd卡写数据
    权限<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    try {
    //得到sd卡路径
    String str = Environment.getExternalStorageDirectory().getPath();
          File file = new File(str, "测试.txt");
         FileOutputStream fos = new FileOutputStream(file);
         fos.write("测试".getBytes());
         fos.close();
         } catch (Exception e) {
           Toast.makeText(FileStudyActivity.this, "失败啊", 1).show();
            // TODO Auto-generated catch block
           e.printStackTrace();
                            }


    //判断sd卡状态
    if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
          Toast.makeText(FileStudyActivity.this, "sd卡可用", 1).show();

    }
    else{
          Toast.makeText(FileStudyActivity.this, "sd卡不可用", 1).show();
    }

    获取sd卡空间数据

    //得到路径
    File file = Environment.getExternalStorageDirectory();
     long totaSpace = file.getTotalSpace();//总大小
     long usablespace = file.getUsableSpace();//可用空间
     //转换格式
    t1.setText(t1.getText()+Formatter.formatFileSize(this, totaSpace));
    t2.setText(t2.getText()+Formatter.formatFileSize(this, usablespace));
    文件权限
    // 按钮点击事件
    public void click1(View v) {
          try {
                FileOutputStream fos = openFileOutput("私有.txt", MODE_PRIVATE);
          fos.write("私有文件演示".getBytes());
          fos.close();
    } catch (Exception e) {
          // TODO Auto-generated catch block
                e.printStackTrace();
          }
    }
    // 按钮点击事件
    public void click2(View v) {
          try {
                FileOutputStream fos = openFileOutput("可追加.txt", MODE_APPEND);
                fos.write("可追加文件演示".getBytes());
                fos.close();
          } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
          }
    }
    // 按钮点击事件
    public void click3(View v) {
          try {
                FileOutputStream fos = openFileOutput("可读.txt", MODE_WORLD_READABLE);
                fos.write("可读文件演示".getBytes());
                fos.close();
          } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
          }
    }
    // 按钮点击事件
    public void click4
    (View v) {
          try {
                FileOutputStream fos = openFileOutput("可写.txt", MODE_WORLD_WRITEABLE);
                fos.write("可写文件演示".getBytes());
                fos.close();
          } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
          }
    }

    xml文件
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        >
        <Button
            android:onClick="click1"
            android:id="@+id/button1"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="私有" />
        <Button
            android:id="@+id/button2"
            android:onClick="click2"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="可追加" />
        <Button
            android:id="@+id/button3"
            android:onClick="click3"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="可读" />
        <Button
            android:id="@+id/button4"
            android:onClick="click4"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="可写" />
    </LinearLayout>

    SharedPreferences介绍(*****)
    用法:
    【1】获取sp实例
    【2】获取编辑器   Edit edit = sp.edit();
    【3】存数据          edit.put类型();
    【4】提交             edit.commit();
    public void click5(View v) {
    //拿到实例(通过上下文)
          /**
           * 第一个参数会帮我们生成一个xml文件
           * 第二个参数代表文件权限
           */
          SharedPreferences sp = getSharedPreferences("user", 0);
          //获取sp的编辑器
          Editor edit = sp.edit();
          edit.putString("name", "登录名");
          edit.putString("pwd", "密码");
          //提交
          edit.commit();
    }
    //读取
    public void click6(View v){
          //先初始化sp实例
          SharedPreferences sp = getSharedPreferences("user", 0);
          String str = "";
          str += sp.getString("name", "");
          str += sp.getString("pwd", "");
          Toast.makeText(this, str, 1).show();
    }


    生成xml
    第一种 自己拼接
    public void click7(View v) {
          List<Sms> smsLists = new ArrayList<Sms>();
          for (int i = 0; i < 10; i++) {
                smsLists.add(new Sms("100" + i, "你好" + i));
          }
          StringBuffer sb = new StringBuffer();
          sb.append("<?xml version=\"+1.0\" encoding=\"utf-8\"?>");
          sb.append("<smss>");
          for(Sms sms : smsLists){
                sb.append("<sms>");
                sb.append("<name>"+sms.getName());
                sb.append("</name>");
                sb.append("pwd"+sms.getPwd());
                sb.append("</pwd>");
                sb.append("</sms>");
          }
          sb.append("</smss>");
          //保存
          File file = new File(Environment.getExternalStorageDirectory(),"MyUser.xml");
          try {
                FileOutputStream fos = new FileOutputStream(file);
                fos.write(sb .toString().getBytes());
                fos.close();
          } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
          }
    }

    第二种
    public void click8(View v) {
          List<Sms> smsLists = new ArrayList<Sms>();
          for (int i = 0; i < 10; i++) {
                smsLists.add(new Sms("100" + i, "你好" + i));
          }
          // 获取xmlSerializer类的实例, 通过Xml这个工具类获取
          XmlSerializer xsl = Xml.newSerializer();
          // 设置Xmlserializer序列化器参数
          File file = new File(Environment.getExternalStorageDirectory()
                      .getPath(), "MyUser2.xml");
          try {
                FileOutputStream fos = new FileOutputStream(file);
                xsl.setOutput(fos, "utf-8");
                // 开始写xml文档开头
                xsl.startDocument("utf-8", true);
                // 写xml的根节点 第一个参数:命名空间 第二个参数 标签名
                xsl.startTag(null, "smss");
                //
                for (Sms sms : smsLists) {
                      xsl.startTag(null, "sms");
                      xsl.startTag(null, "name");
                      xsl.text(sms.getName());
                      xsl.endTag(null, "name");
                      xsl.startTag(null, "pwd");
                      xsl.text(sms.getPwd());
                      xsl.endTag(null, "pwd");
                      xsl.endTag(null, "sms");
                }
                xsl.endTag(null, "smss");
                // 文档结尾
                xsl.endDocument();
          } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
          }
    }

    Xml解析
    解析步骤
    【1】获取XmlPullParser
    【2】设置XmlPullParser的参数
    【3】获取解析文档的事件类型
    【4】具体判断一下是哪个标签
    public static List<Channel> parserXml(InputStream in) throws Exception {
         List<Channel> weatherLists = null;
         // 1、获取XmlPullParser 解析的实例
         XmlPullParser parser = Xml.newPullParser();
         // 2、设置XmlPullParser 的参数
         parser.setInput(in, "utf-8");
         // 3、获取事件类型
         int type = parser.getEventType();
         while (type != XmlPullParser.END_DOCUMENT) {
              // 4、具体判断一下解析到了哪个节点
              switch (type) {
              // 解析开始
              case XmlPullParser.START_TAG:
                  if ("weather".equals(parser.getName())) {
                       // 创建一个集合对象
                       weatherLists = new ArrayList<Channel>();
                  } else if ("channel".equals(parser.getName())) {
                       // 属性值
                       String str1 = parser.getAttributeValue(0);
                  } else if ("city".equals(parser.getName())) {
                       // 两个标签之中的值
                       String city = parser.nextText();
                  }
                  break;
              // 解析结束
              case XmlPullParser.END_TAG:
                  break;
              }
              // 不停的向下解析
              parser.next();
         }
         return null;
    }

    获取资产的管理者(安卓工程assets目录下的文件)
    InputStream is = getAssets().open(文件名);

    数据库
    (在有大量数据需要存储的时候需要用到数据库)
    使用SQLLite Expert Professionan这个工具
    可以打开创建的数据库
    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteDatabase.CursorFactory;
    import android.database.sqlite.SQLiteOpenHelper;
    public class MyOpenHelper extends SQLiteOpenHelper {
         /**
          * @param context
          * @param name
          * @param factory
          * @param version
          *            name第二个参数:数据库的名字 第三个参数:目的创建Cursor对象 第四个参数:数据库的版本 从1开始
          */
         public MyOpenHelper(Context context) {
              super(context, "MySQL.db", null, 1);
         }
         /*
          * (non-Javadoc)
          *
          * @see
          * android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite
          * .SQLiteDatabase) 当数据库第一次创建时调用 这个方法特别适合做表结构的初始化
          */
         @Override
         public void onCreate(SQLiteDatabase db) {
              // id一般以下划线开头
              db.execSQL("Create table info(_id interger primary key, name varchar(20))");
         }
         @Override
         public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
         }
    }
    ----------------------------------------
    调用
    // 打开数据库或者创建数据库 如果是第一次就创建
    MyOpenHelper myOpenHelper = new MyOpenHelper(getApplicationContext());
    // 打开数据库或者创建数据库 如果是第一次就创建 如果磁盘满了 返回只读的
    SQLiteDatabase sqliteDatabase = myOpenHelper.getWritableDatabase();
    //SQL语句
    db.execSQL("insert into info(name, phone) values(?,?)",new Object[]{"张三","15055819391"});
    //数据库用完需要关闭
    db.close();
    //查找
    Cursor cursor= db.rawQuery(参数1, 参数2);
    if(cursor != null && cursor.getCount()>0){
         while(cursor.moveToNext()){
              String name = cursor.getString(1);
    }

    }
    cursor.close();
    ----------------------------------------
    使用谷歌提供操作数据库的方法
    添加 : ContentValues values = new ContentValues();
                   values.put("name", "王五");
                   values.put("phone", "110");
                   long insert = db.insert("表名", null, values);//返回插入新行id, >0添加成功
                   db.close();
    删除 ; int delete = db.delete("表名", "name=?", new String[]{"王五"});//删除的行数
                  db.close();
    更新 : ContentValues values = new ContentValues();
                int update = db.update("表名",values, "name=?", new String[]{"王五"});//代表更新了多少行
              第二个参数代表要查询的列(null代表所有列)
             第三个参数代表查询根据
    第五个参数是否分组
    第七个是否排序
    查找 : Cursor cursor = db.quary("表名", new String[]{"phone"}, "name=?", new String[]{"王五"}, null, null, null);
         
    ListVIew 
    import org.w3c.dom.Text;
    import android.content.Context;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.TextView;
    public class Base extends BaseAdapter {
         Context context;
         Base(ListAgainStudy con) {
              this.context = con;
         }
         public int getCount() {
              return 100;
         }
         public Object getItem(int position) {
              return null;
         }
         public long getItemId(int position) {
              return 0;
         }
         public View getView(int position, View conTextView, ViewGroup arg2) {
    //        代码优化
              TextView tv = null;
              if (conTextView == null) {
    //            创建新的view 对象
                  tv = new TextView(context);
              } else {
    //            复用历史缓存对象
                  tv = (TextView) conTextView;
              }
              tv.setText("haha"+position);
              return tv;
         }
    }

    调用

    listView = (ListView) findViewById(R.id.list1);
    listView.setAdapter(new Base(this));
    LIstView 的奇怪现象

    注意:在使用ListView 时,XML文件中ListView 属性的高应该使用(匹配父控件), 不应该使用(包裹内容),因为使用(包裹内容)
    效率低

    列表复杂界面(使用打气筒)
    private class MyBase extends BaseAdapter {
         public int getCount() {
              return 20;
         }
         public Object getItem(int position) {
              return null;
         }
         public long getItemId(int position) {
              return 0;
         }
         public View getView(int position, View convertView, ViewGroup parent) {
              View view;
              if(convertView == null){
    //                 打气筒 : 可以通过一个打气筒把一个资源布局转换成一个view 对象
    //                 第二个参数:  布局文件
    //                 第三个参数: 用不到
                  view = View.inflate(getApplicationContext(), R.layout.item, null);
              }else{
    //                 复用历史缓存对象
                  view = convertView;
              }
              
              return view;
         }
    }

    TextView 
    单行显示
    android:singleLine="true"
    ...
    android:ellipsize="end"

    线性布局, 相对布局 都继承自ViewGroup 可以有自己的孩子


    打气筒详解(inflate)
    第一种:
    view = View.inflate(getApplicationContext(), R.layout.item, null);
    第二种:
    LayoutInflater.from(getApplicationContext()).inflate(R.layout.item, null);
    第三种:
    (工作中常见)
    LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
    inflater.inflate(R.layout.item, null);

    Adaper作用:把数据展示到ListView上
    ArrayAdapter适配器
    public class Arrayadapter extends Activity {
         private ListView lv;
         String object[] = { "老张", "老方", "老李", "老王", "老毕", "老师", "老孙" };
         @Override
         protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.array);
              lv = (ListView) findViewById(R.id.ALV);
              // 创建一个ArrayAdapter
              ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                       R.layout.aarrayitem, object);
              // 设置数据适配器
              lv.setAdapter(adapter);
         }
    }
    xml:
    array:
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >
        <ListView
            android:id="@+id/ALV"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >
        </ListView>
    </LinearLayout>

    arrayitem:
    <?xml version="1.0" encoding="utf-8"?>
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </TextView>
     SimpleAdapter适配器
    使用map封装数据
    public class Simplleadapter extends Activity {
         @Override
         protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.sim);
              ListView lv = (ListView) findViewById(R.id.SLV);
              // 准备数据
              List<Map<String, String>> data = new ArrayList<Map<String, String>>();
              Map<String, String> map1 = new HashMap<String, String>();
              map1.put("name", "张三");
              map1.put("phone", "88888888");
              Map<String, String> map2 = new HashMap<String, String>();
              map2.put("name", "赵云");
              map2.put("phone", "66668888");
              Map<String, String> map3 = new HashMap<String, String>();
              map3.put("name", "貂蝉");
              map3.put("phone", "12345678");
              data.add(map1);
              data.add(map2);
              data.add(map3);
              SimpleAdapter adapter = new SimpleAdapter(getApplicationContext(),
                       data, R.layout.sim1, new String[] { "name", "phone" },
                       new int[] { R.id.stv1, R.id.stv2 });
              lv.setAdapter(adapter);
              TextView tv = (TextView) findViewById(R.id.smiantv);
              tv.setText("源码:\nSimpleAdapter adapter = new SimpleAdapter(getApplicationContext(), data, R.layout.sim1, new String[]{\"name\", \"phone\"}, new int[]{R.id.stv1, R.id.stv2});");
         }
    }




    权重只在线性布局中使用

    网络编程
    HttpURLConnection用于发送和接收数据


    android.os.NetworkOnMainThreadException是说不要在主线程中访问网络,这个是android3.0版本开始就强制程序不能在主线程中访问网络,要把访问网络放在独立的线程中。

        在开发中,为了防止访问网络阻塞主线程,一般都要把访问网络放在独立线程中或者异步线程AsyncTask中。


    1、想要忽略这些强制策略问题的话,可以在onCreate()方法里面加上
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);

     并在方法上加上@SuppressLint("NewApi"),重试,OK。
    只有主线程才能更新UI
    Handler使用
    Handler作用:是用来发消息和处理消息
    Lopper作用: 去消息队列里面取消息(主线程一创建Lopper就有了) 

    在主线程中定义
    private Handler handler = new Handler() {
              public void handleMessage(Message msg) {
                  // 可以在主线程中更新UI
                  String content = (String) msg.obj;
                  tv.setText(content);
              }
         };

    点击事件
    public void click(View v) {
         new Thread() {
              public void run() {
                  // 获取源码路径
                  String path = ed.getText().toString();
                  path = "http://" + path;
                  // HttpURLConnection
                  try {
                       URL url = new URL(path);
                       HttpURLConnection conn = (HttpURLConnection) url
                                 .openConnection();
                       conn.setRequestMethod("GET");// 要求大写
                       // 设置请求的超时时间
                       conn.setConnectTimeout(5000);
                       // 获取服务器返回的状态吗
                       int code = conn.getResponseCode();
                       // 如果code == 200 请求成功
                       if (code == 200) {
                            // 过去服务器返回的数据 是以流的方式返回
                            InputStream in = conn.getInputStream();
                            // 把流里面的数据显示到文本标签上
                            // 把流转换成字符串 (做成工具类)
                            String content = StreamTools.readStream(in);
                            // tv.setText(content);
                            // 拿着我们创建的handler(助手)告诉系统需要更新UI
                            Message msg = new Message();
                            msg.obj = content;
                            handler.sendMessage(msg);// 发送一条消息, 消息
                       }
                  } catch (Exception e) {
                       // TODO Auto-generated catch block
                       e.printStackTrace();
                  }
              }
         }.start();
    }

    图片查看器
    1、把流信息转换成bitmap对象
    2、bitmapFactory.decodeStream(imputStream in)
    3、加上网络访问权限


    //这句API不管在什么地方调用 action都运行在UI线程路
    runOnUiThread(action)

    runOnUiThread(new Runnable(){
    public void runn(){
    //动作
    }
    });
    1、如果仅仅就是更新UI  那么就用runOnUiThread 这个API就可以
    2、有的时候可以通过Handler 发送消息  携带数据, 这个时候必须的用Handler
    API:应用开发接口
    Handler
    protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.main);
              new Handler().postDelayed(new Runnable() {
                  public void run() {
                       // TODO Auto-generated method stub
                       Toast.makeText(getApplicationContext(), "handler等待5s显示", 1)
                                 .show();
                       TextView tv = (TextView) findViewById(R.id.button1);
                       tv.setText("5s后显示");
                  }
              }, 5000);
         }





    展开全文
  • Android学习笔记

    千次阅读 2019-03-29 23:29:29
    安装步骤 ... 一.LinearLayout线性布局 //宽度高度单位使用dp,不是px. 字体使用sp单位 layout_width:match_parent 和父亲一样宽 gravity:center ...//内部元素排列方式 View是所有其他的父类 ...均...


    下篇: https://blog.csdn.net/wang342626/article/details/87917342


    Android studio安装步骤

    https://blog.csdn.net/siwuxie095/article/details/53431818

    真机运行步骤

    Android Studio 使用USB真机调试教程教程:
    https://blog.csdn.net/fubo1990/article/details/79798328
    no target device found 问题解决链接:
    https://blog.csdn.net/aaa1050070637/article/details/82146281

    一.LinearLayout线性布局

        //宽度高度单位使用dp,不是px. 字体使用sp单位
        layout_width:match_parent 和父亲一样宽
        gravity:center ...//内部元素排列方式
    

    View是所有其他的父类

    均分宽度
    使用weight

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:background="#00FF00"
        android:layout_marginTop="10dp"
    
        <view
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"> //均分宽度
        </view>
    
        <view
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:background="#FF0000"
            android:layout_weight="1">
        </view>
    </LinearLayout>
    

    均分宽度

    宽度占五分之二

    weight权重,减掉占用的,剩下的平分

    二. RelativeLayout 相对布局

    android:layout_alignParentBottom="true"  //靠近父亲的底部对
    
    android:layout_toRightOf="@+id/view_1"> // 靠view_1的右边
    
    
    android:layout_below="@id/view_1"> // 放view_1的下边
    
    

    更多 https://www.cnblogs.com/tinyphp/p/3787994.html

    三: TextView

    新手全部流程:

    1. 打开app->src->main->res->layout->activity_main.xml 写入代码
    <!--创建一个Button-->
    <Button
            android:id="@+id/btn_textview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="TextView"/>
    
    
    1. 打开app->src->main->java->com.*.myApplication->MainActivity.java写入代码
    package com.example.qing.myapplication2;
    
    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    
    //有的人使用的是 extends AppCompatActivity 与我不一样
    public class MainActivity extends Activity {
    
        //代码1: 首先声明全局的Button
        private Button mBtnTextview;
    
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
    
                // 代码2: 通过id获取Button,必要时需要把view强制转换为Button类型
                mBtnTextview = findViewById(R.id.btn_textview);
                // 代码3: 添加Button的点击事件
                mBtnTextview.setOnClickListener(new View.OnClickListener(){
                    @Override
                    public void onClick(View v){
                        //代码4: 跳转到TextView界面
                        Intent intent =  new Intent(MainActivity.this,TextViewActivity.class);
                        //注意这个TextViewActivity.class名称要与接下来步骤2创建的TextViewActivity.java名称相匹配
                        startActivity(intent);
                    }
                });
        }
    }
    
    
    1. 建立一个Activity
       在左侧栏,MainActivity.java处右击, new->Activity->EmptyActivity, 然后起个名字叫TextViewActivity,确定后, 将会自动产生 TextViewActivity.java 和 activity_text_view.xml 这两个文件, 后一个文件在 src->main->res->layout下面
       并且打开 AndroidManifest.xml (app->src->main文件夹下面)看看有没有自动创建下面的代码
    <activity android:name=".TextViewActivity" />
    

     没有自动创建,那就手动添加

    1. 打开activity_text_view.xml, 修改android.support.constraint.ConstraintLayout为
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
    android:orientation="vertical"
        tools:context="com.example.qing.myapplication2.TextViewActivity">
    <!--android:orientation="vertical"设置为竖行显示-->
    
    
        <TextView
            android:id="@+id/tv_1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
         android:text="@string/tv_text1"/>
         <!--@string/tv_text1表示引用strings.xml  ( app->src->main->res->values->strings.xml )
            中的名称为tv_text1的文本,
            需要在那里添加代码<string name="tv_text1">天哥在奔跑</string>  -->
         <!--字体大小单位用sp-->
    
    </LinearLayout
    

    并且编辑 app->src->main->res->values->strings.xml, 添加一个string
    <string name="tv_text1">天哥在奔跑</string> 给上面的来引用。
    还有最简单的方法就是 直接写
    android:text="天哥在奔跑" 简单方便。这样子预览效果为
    效果1

    5.为了实现文本缩写的效果
    在这里插入图片描述
    继续添加下面的代码即可

    <TextView
            android:id="@+id/tv_2"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
        android:maxLines="1"
        android:ellipsize="end"
            android:textColor="#000000"
            android:textSize="24sp"
            android:layout_marginTop="10dp"
            android:text="天哥在奔跑"/>
       <!--maxLines强制设置为1行文字-->
       <!--ellipsize设置末尾显示不全修改为...-->
       <!--android:text="天哥在奔跑" 等价于上面的引用 --
    
    1. 为了完成带图标的文本的效果

    在这里插入图片描述
    写入代码

    <TextView
            android:id="@+id/tv_3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#000000"
            android:textSize="24sp"
            android:layout_marginTop="10dp"
            android:text="筛选"
       android:drawableRight="@drawable/icon_arrow_off"
        android:drawablePadding="5dp"
            />
       <!--android:drawableRight="@drawable/icon_arrow_off"表示引用drawable文件夹下面的.png图片,放在文字的右边-->
       <!--android:drawablePadding="5dp"表示离文字距离5单位-->
    

    并且在左侧栏app->src->main->res->drawable文件夹下面添加icon_arrow_off.png即可, 图标可以去阿里巴巴图标库下载 , 注意图标尺寸大小

    1. 为了完成删除线的效果
      删除线效果图
      先在 activity_text_view.xml 文本中创建TextView, 设好id名字
      然后打开 TextView.java 写入代码
    package com.example.qing.myapplication2;
    
    import android.app.Activity;
    import android.graphics.Paint;
    import android.os.Bundle;
    import android.widget.TextView;
    
    public class TextViewActivity extends Activity {
    
        //代码1: 声明全局变量
        private TextView mTv4;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_text_view);
    
            //代码2: 通过id获取TextView
            mTv4 = findViewById(R.id.tv_4);
            //代码3.1: 画一个穿过去的线
            mTv4.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG);
            //代码3.2: 去掉锯齿
            mTv4.getPaint().setAntiAlias(true);
        }
    }
    
    1. 为了实现文本加下划线的效果
      下划线效果图

    先在 activity_text_view.xml 文本中创建TextView, 设好id名字
    然后打开 TextView.java 写入代码

    package com.example.qing.myapplication2;
    
    import android.app.Activity;
    import android.graphics.Paint;
    import android.os.Bundle;
    import android.text.Html;
    import android.widget.TextView;
    
    public class TextViewActivity extends Activity {
    
        //代码1: 声明全局变量
        private TextView mTv5;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_text_view);
    
            //代码2: 通过id获取TextView
            mTv5 = findViewById(R.id.tv_5);
            //代码3: 画一个下划线
            mTv5.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG);
        }
    }
    
    
    1. 实现文本加下划线的另一种方法(HTML代码实现的方法)
      下划线效果图

    先在 activity_text_view.xml 文本中创建TextView, 设好id名字,注意这里的text是空文本 android:text="" 这样子
    然后打开 TextView.java 写入代码

    package com.example.qing.myapplication2;
    
    import android.app.Activity;
    import android.graphics.Paint;
    import android.os.Bundle;
    import android.text.Html;
    import android.widget.TextView;
    
    public class TextViewActivity extends Activity {
    
        //代码1: 声明全局变量
        private TextView mTv6;
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_text_view);
    
            //代码2: 通过id获取TextView
            mTv6 = findViewById(R.id.tv_6);
            //代码3: 设置文本为HTML代码, u表示HTML代码中加了下划线
            mTv6.setText(Html.fromHtml("<u>天哥在奔跑</u>"));
            
        }
    }
    
    
    1. 为了实现文本跑马灯的效果
    <TextView
            android:id="@+id/tv_7"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:textColor="#000000"
            android:textSize="24sp"
    
         android:text="天哥在奔跑天哥在奔跑天哥在奔跑天哥在奔跑"
         android:singleLine="true"
         android:ellipsize="marquee"
         android:marqueeRepeatLimit="marquee_forever"
         android:focusable="true"
         android:focusableInTouchMode="true" />
        <!--文本字多一点,单行显示,滚动方式,永远滚动,并且获得焦点才行-->
    
    

    四. Button

    1. 打开app->src->main->res->layout->activity_main.xml ,写入代码来创建一个Button, 需要注意父元素的布局如果是LinearLayout则要加上 android:orientation="vertical"
    <!--创建一个Button-->
        <Button
            android:id="@+id/btn_button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Button"/>
    
    1. 建立一个Activity
       在左侧栏,MainActivity.java处右击, new->Activity->EmptyActivity, 然后起个名字叫ButtonActivity,确定后, 将会自动产生 ButtonActivity.java 和 activity_button.xml 这两个文件, 后一个文件在 src->main->res->layout下面
       并且打开 AndroidManifest.xml (app->src->main文件夹下面)看看有没有自动创建下面的代码
    <activity android:name=".ButtonActivity"></activity>
    

     没有自动创建,那就手动添加

    1. 打开 MainActivity.java 写入代码
    package com.example.qing.myapplication2;
    
    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    
    public class MainActivity extends Activity {
    
        //代码1: 声明全局的Button
        private Button mBtnButton;
    
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
    
                //代码2: 通过id获取Button,必要时需要把view强制转换为Button类型
                mBtnButton = findViewById(R.id.btn_button);
                //代码3: 添加Button点击事件
                mBtnButton.setOnClickListener(new View.OnClickListener(){
                    @Override
                    public void onClick(View v){
                        //代码4: 跳转到ButtonAvtivity界面
                        Intent intent = new Intent(MainActivity.this,ButtonActivity.class);
                        //注意这个ButtonActivity.class名称要与上面步骤2创建的ButtonActivity.java名称相匹配
                        startActivity(intent);
                    }
                });
        }
    }
    
    
    1. 打开 activity_button.xml 修改为RelativeLayout布局, 并且写入代码
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="10dp"
        tools:context="com.example.qing.myapplication2.ButtonActivity">
    
    	<!--创建按钮1-->
        <Button
            android:id="@+id/btn_1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="按钮1"
            android:textSize="20sp"
            android:textColor="#0066FF"
            android:background="#FF0000"/>
    
    </RelativeLayout>
    
    1. 为了创建圆角矩形的按钮2
    • 先左侧栏res->drawable右击, new->Drawable resource file,
      在这里插入图片描述
    • 打开bg_btn2.xml 写入代码
    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
    
        <!--实心橙色-->
        <solid android:color="#FF9900" />
    
        <!--圆角10dp-->
        <corners android:radius="10dp" />
    
    </shape>
    
    • 打开 activity_button.xml 写入代码
    <!--创建实心圆角矩形按钮2-->
        <Button
            android:id="@+id/btn_2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="按钮2"
            android:textSize="20sp"
            android:textColor="#0066FF"
            android:layout_below="@id/btn_1"
            android:layout_marginTop="10dp"
            android:background="@drawable/bg_btn2"/>
        <!--背景调用drawable的实心圆角矩形-->
    
    
    • 效果图
      实心圆角矩形效果图
    1. 为了实现按钮3只有边框的效果, 太丑,有待改进
      在这里插入图片描述
    • 先在activity_button.xml中写入代码, 来添加一个button3
    <Button
            android:id="@+id/btn_3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="按钮3"
            android:textSize="20sp"
            android:textColor="#0066FF"
            android:layout_below="@id/btn_2"
            android:layout_marginTop="10dp"
            android:background="@drawable/bg_btn3"/>
        <!--背景调用drawable的圆角边框矩形-->
    
    • 然后新建一个Drawable
      在这里插入图片描述

    写入代码

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
    
        <!--橙色边框 ,一定要有宽度为1dp-->
        <stroke android:width="1dp" android:color="#FF9900"/>
    
        <!--圆角10dp-->
        <corners android:radius="10dp"/>
    </shape>
    
    1. 为了实现按钮4按压变色的效果
    • 先写入代码,创建一个Button4
    <!--按压的效果-->
        <Button
            android:id="@+id/btn_4"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="按钮4"
            android:textSize="20sp"
            android:textColor="#0066FF"
            android:layout_below="@id/btn_3"
            android:layout_marginTop="10dp"
            android:background="@drawable/bg_btn4"/>
    
    
    • 然后创建一个Drawable
      在这里插入图片描述
      写入代码
    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <!--按压的时候-->
        <item android:state_pressed="true">
            <shape>
                <solid android:color="#CC7A00" />
                <corners android:radius="10dp" />
            </shape>
        </item>
    
        <!--没有按压时的效果-->
        <item android:state_pressed="false">
            <shape>
                <solid android:color="#FF9900" />
                <corners android:radius="10dp" />
            </shape>
        </item>
    
    </selector>
    
    1. 为了实现按钮4点击弹出提示信息的效果
      在这里插入图片描述
    • 打开activity_button.xml添加点击事件
    <Button
            android:id="@+id/btn_4"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="按钮4"
            android:textSize="20sp"
            android:textColor="#0066FF"
            android:layout_below="@id/btn_3"
            android:layout_marginTop="10dp"
            android:background="@drawable/bg_btn4"
            android:onClick="showToast"/>
    	<!--onClick事件-->
    
    
    • 打开ButtonActivity.java,添加一个函数,代码如下:
        //显示提示信息的函数
        public void showToast(View view){
            Toast.makeText(this,"我被点击了",Toast.LENGTH_SHORT).show();
        }
    
    1. 为按钮3添加点击事件的另一种方法
      (这是常用的方法,这方法也可以为TextView设置点击事件)
      打开ButtonActivity.java写入代码:
    package com.example.qing.myapplication2;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.Toast;
    
    public class ButtonActivity extends AppCompatActivity {
    
        //代码1: 声明全局变量
        private Button mBtn3;
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_button);
    
            //代码2: 通过id获取Button
            mBtn3 = (Button) findViewById(R.id.btn_3);
            //代码3: 添加点击事件
            mBtn3.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Toast.makeText(ButtonActivity.this,"按钮3被点击了,这是最常用的点击事件",Toast.LENGTH_LONG).show();
                }
            });
    
        }
    }
    
    
    

    五. EditText 来实现登录

    1. 打开activity_main.xml 添加一个按钮 btn_edittext ,用来点击跳到新的页面来演示
    2. 打开MainActivity.java,为刚才的按钮添加点击事件,跳到新的页面来演示
    package com.example.qing.myapplication2;
    
    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    
    public class MainActivity extends Activity {
    
        //代码1: 首先声明全局的Button
        private Button mBtnTextview;
        private Button mBtnButton;
        private Button mBtnEditText;
    
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
    
                // 代码2: 通过id获取Button,必要时需要把view强制转换为Button类型
                mBtnTextview = findViewById(R.id.btn_textview);
                // 代码3: 添加Button的点击事件
                mBtnTextview.setOnClickListener(new View.OnClickListener(){
                    @Override
                    public void onClick(View v){
                        //代码4: 跳转到TextView界面
                        Intent intent =  new Intent(MainActivity.this,TextViewActivity.class);
                        //注意这个TextViewActivity.class名称要与接下来步骤2创建的TextViewActivity.java名称相匹配
                        startActivity(intent);
                    }
                });
    
                //代码2: 通过id获取Button,必要时需要把view强制转换为Button类型
                mBtnButton = findViewById(R.id.btn_button);
                //代码3: 添加Button点击事件
                mBtnButton.setOnClickListener(new View.OnClickListener(){
                    @Override
                    public void onClick(View v){
                        //代码4: 跳转到ButtonAvtivity界面
                        Intent intent = new Intent(MainActivity.this,ButtonActivity.class);
                        //注意这个TextViewActivity.class名称要与接下来步骤2创建的TextViewActivity.java名称相匹配
                        startActivity(intent);
                    }
                });
    
                //代码2: 通过id获取EditText
                mBtnEditText = findViewById(R.id.btn_edittext);
                //代码3: 添加点击事件
                mBtnEditText.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        //代码4: 跳转到EditTextAvtivity界面
                        Intent intent = new Intent(MainActivity.this,EditTextActivity.class);
                        //注意这个TextViewActivity.class名称要与接下来步骤2创建的TextViewActivity.java名称相匹配
                        startActivity(intent);
                    }
                });
        }
    }
    
    
    1. 在左侧栏src->java->com.*.myapplication2下面新建一个EmptyActivity, 起名字叫EditTextActivity, 系统会自动创建 EditTextActivity.java 和 activity_edit_text.xml 并且在AndroidManifest.xml 自动帮我们添加下面的声明
    <activity android:name=".EditTextActivity"></activity>
    
    1. 打开activity_edit_text.xml写入代码
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="15dp">
    
        <EditText
            android:id="@+id/et_1"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:textSize="16sp"
            android:textColor="#FFAD33"
            android:hint="用户名"
            android:background="@drawable/bg_username"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:drawableLeft="@drawable/icon_user"
            />
        <!--android:hint="用户名" 设置为提示符的效果-->
        <!--android:background="@drawable/bg_username" 背景设为橙色边框-->
        <!--android:drawableLeft="@drawable/icon_user" 设置左侧显示图标-->
    
        <EditText
            android:id="@+id/et_2"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:layout_below="@id/et_1"
            android:textSize="16sp"
            android:textColor="#FFAD33"
            android:hint="密码"
            android:inputType="textPassword"
            android:background="@drawable/bg_username"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:layout_marginTop="20dp"
            android:drawableLeft="@drawable/icon_password"
            />
        <!--inputType="textPassword" 设置为看不见明文的效果-->
    
        <Button
            android:id="@+id/btn_login"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:text="登录"
            android:layout_below="@+id/et_2"
            android:layout_marginTop="20dp"
            android:textColor="#ffffff"
            android:background="@drawable/bg_btn4"
            />
        <!--android:background="@drawable/bg_btn4" 背景设置为带有按压的效果-->
        <!--通过java代码来添加点击事件-->
    
    </RelativeLayout>
    
    
    1. 注意上面需要引用两个icon , 和带有边框效果的背景, 还有带有按压效果的背景, 请参考前面的button章节
    2. 打开EditTextActivity.java写入代码, 来添加按钮点击事件
    package com.example.qing.myapplication2;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.Toast;
    
    public class EditTextActivity extends AppCompatActivity {
    
        private Button mBtnLogin;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_edit_text);
    
            //通过id获取button,并添加点击事件
            mBtnLogin = (Button) findViewById(R.id.btn_login);
            mBtnLogin.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    //弹出消息提示框
                    Toast.makeText(EditTextActivity.this,"登录成功",Toast.LENGTH_SHORT).show();
                }
            });
        }
    }
    
    
    1. EditText添加其他事件
    		//声明全局的变量
    		private EditText mEtUserName;
    		
    		//下面写到onCreate函数中
    		
            mEtUserName = (EditText) findViewById(R.id.et_1);
            mEtUserName.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    
                }
    
                @Override
                public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                    //最常用的函数
                    //打印内容,Android Monitor里面看到输出文本
                    Log.d("文本是:",charSequence.toString());
                }
    
                @Override
                public void afterTextChanged(Editable editable) {
    
                }
            });
    

    六.RadioButton

    1. 打开MainActivity.java, 添加一个Button跳转到RadioButtonActivity界面, 并且简化一下代码
    package com.example.qing.myapplication2;
    
    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    
    public class MainActivity extends Activity {
    
        //代码1: 首先声明全局的Button
        private Button mBtnTextview;
        private Button mBtnButton;
        private Button mBtnEditText;
        private Button mBtnRadoiButton;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
    
            // 代码2: 通过id获取Button,必要时需要把view强制转换为Button类型
            mBtnTextview = findViewById(R.id.btn_textview);
            //通过id获取Button,必要时需要把view强制转换为Button类型
            mBtnButton = findViewById(R.id.btn_button);
            //通过id获取EditText
            mBtnEditText = findViewById(R.id.btn_edittext);
            //通过id获取RadoiButton
            mBtnRadoiButton = findViewById(R.id.btn_radiobutton);
    
            //给上面几个全都添加点击事件
            setListener();
        }
    
        //添加监听器
        private void setListener(){
            OnClick onClick = new OnClick();
            mBtnTextview.setOnClickListener(onClick);
            mBtnButton.setOnClickListener(onClick);
            mBtnRadoiButton.setOnClickListener(onClick);
        }
    
    
        private class OnClick implements View.OnClickListener{
    
            @Override
            public void onClick(View v) {
                Intent inten = null;
                switch (v.getId()){
                    case R.id.btn_textview:
                        inten = new Intent(MainActivity.this,TextViewActivity.class);
                        break;
                    case R.id.btn_button:
                        inten = new Intent(MainActivity.this,ButtonActivity.class);
                        break;
                    case R.id.btn_edittext:
                        inten = new Intent(MainActivity.this,EditTextActivity.class);
                        break;
                    case R.id.btn_radiobutton:
                        inten = new Intent(MainActivity.this,RadioButtonActivity.class);
                        break;
                }
                startActivity(inten);
            }
        }
    }
    
    
    1. 新建一个EmptyActivity起名字叫 RadioButtonActivity,系统会自动完成3件事,
    2. 打开activity_radio_button.xml, 写入代码
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >
    
    
        <!--设置效果1-->
        <RadioGroup
            android:id="@+id/rg_1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:paddingLeft="20dp"
            >
            <!--RadioGroup里面的RadioButton必须要设置id-->
    
            <RadioButton
                android:id="@+id/rb_man"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text=""
                android:textSize="18sp"
                android:textColor="#FF6600"
                android:checked="true"
                />
            <!--android:checked="true" 设置默认是选中男-->
    
            <RadioButton
                android:id="@+id/rb_woman"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text=""
                android:textSize="18sp"
                android:textColor="#FF6600"
                />
        </RadioGroup>
    
    
        <!--设置效果2,更好看点-->
        <RadioGroup
            android:id="@+id/rg_2"
            android:orientation="horizontal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/rg_1"
            android:layout_marginTop="30dp"
            android:paddingLeft="20dp"
            >
    
            <RadioButton
                android:id="@+id/rb_male"
                android:layout_width="60dp"
                android:layout_height="30dp"
                android:gravity="center"
                android:text=""
                android:textSize="18sp"
                android:textColor="#FF6600"
                android:checked="true"
                android:button="@null"
                android:background="@drawable/selector_orange_radiobutton"
                />
                <!--android:button="@null" 设置去掉前面的圆点-->
                <!--android:gravity="center" 设置文字居中-->
    
            <RadioButton
                android:id="@+id/rb_female"
                android:layout_width="60dp"
                android:layout_height="30dp"
                android:text=""
                android:gravity="center"
                android:background="@drawable/selector_orange_radiobutton"
                android:button="@null"
                android:textSize="18sp"
                android:textColor="#FF6600"
                android:layout_marginLeft="10dp"
                />
        </RadioGroup>
        
    </RelativeLayout>
    
    
    1. 新建一个Drawable文件, 命名为selector_orange_radiobutton.xml,写入代码
    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <!--选中的时候,是橙色的填充背景-->
        <item android:state_checked="true">
            <shape>
                <solid android:color="#AA6600" />
                <corners android:radius="5dp" />
            </shape>
        </item>
    
        <!--没有选中时,是橙色的边框-->
        <item android:state_checked="false">
            <shape>
                <stroke android:width="1dp"
                    android:color="#AA6600"/>
                <corners android:radius="5dp" />
            </shape>
        </item>
    
    </selector>
    
    1. 效果图
      RadioGroup1效果1
      RadioGroup2效果2

    2. 添加点击事件 , 编辑RadioButtonActivity.java

    package com.example.qing.myapplication2;
    
    import android.support.annotation.IdRes;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.widget.RadioButton;
    import android.widget.RadioGroup;
    import android.widget.Toast;
    
    public class RadioButtonActivity extends AppCompatActivity {
    
        private RadioGroup mRg1;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_radio_button);
    
            mRg1 = (RadioGroup) findViewById(R.id.rg_1);
            mRg1.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(RadioGroup radioGroup, @IdRes int i) {
                    //找到被选中的RadioButton
                    RadioButton radioButton = (RadioButton) radioGroup.findViewById(i);
                    //输出radioButton的文本
                    Toast.makeText(RadioButtonActivity.this,radioButton.getText(),Toast.LENGTH_SHORT).show();
                }
            });
    
        }
    }
    
    

    七. CheckBox复选框

    1. 创建一个EmptyActivity命名为CheckBoxActivity, 系统会自动完成3个任务
    2. activity_main.xml中添加一个按钮,点击跳转到新的演示界面, MainActivity.java添加相应的点击事件
    3. 编辑activity_check_box.xml
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="15dp"
        >
    
        <RelativeLayout
            android:id="@+id/rl_1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
    
            <TextView
                android:id="@+id/tv_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="你会哪些编程语言:"
                android:textSize="20sp"
                />
    
            <CheckBox
                android:id="@+id/cb_1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Java"
                android:textSize="20sp"
                android:layout_below="@id/tv_title"
                />
            <CheckBox
                android:id="@+id/cb_2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="C语言"
                android:textSize="20sp"
                android:layout_below="@id/cb_1"
                />
            <CheckBox
                android:id="@+id/cb_3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="C++"
                android:textSize="20sp"
                android:layout_below="@id/cb_2"
                />
            <CheckBox
                android:id="@+id/cb_4"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="C#"
                android:textSize="20sp"
                android:layout_below="@id/cb_3"
                />
    
    
    
        </RelativeLayout>
    
        <!--加了背景的checkbox 更好看点-->
        <RelativeLayout
            android:id="@+id/rl_2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/rl_1">
    
            <TextView
                android:id="@+id/tv_title2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="你的兴趣爱好是:"
                android:textSize="20sp"
                />
    
            <CheckBox
                android:id="@+id/cb_5"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="玩电脑"
                android:textSize="20sp"
                android:layout_below="@id/tv_title2"
                android:button="@drawable/bg_checkbox"
                android:paddingLeft="5dp"
                />
                <!--设置paddingLeft而不是DrawableLeft-->
                <!--设置好背景-->
    
            <CheckBox
                android:id="@+id/cb_6"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="玩手机"
                android:textSize="20sp"
                android:layout_below="@id/cb_5"
                android:button="@drawable/bg_checkbox"
                android:paddingLeft="5dp"
                />
            <CheckBox
                android:id="@+id/cb_7"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="打篮球"
                android:textSize="20sp"
                android:layout_below="@id/cb_6"
                android:button="@drawable/bg_checkbox"
                android:paddingLeft="5dp"
                />
            <CheckBox
                android:id="@+id/cb_8"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="听音乐"
                android:textSize="20sp"
                android:layout_below="@id/cb_7"
                android:button="@drawable/bg_checkbox"
                android:paddingLeft="5dp"
                />
        </RelativeLayout>
    </RelativeLayout>
    
    1. 找到两个icon,还要新建一个Drawable文件,命名为bg_checkbox.xml,写入代码
    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <!--checkbox未选中时,使用icon_checkbox_false.png-->
        <item android:state_checked="false" android:drawable="@drawable/icon_checkbox_false" />
        <!--checkbox选中时,使用icon_checkbox_true.png-->
        <item android:state_checked="true" android:drawable="@drawable/icon_checkbox_true" />
    </selector>
    
    
    1. 效果图
      在这里插入图片描述

    2. 为checkbox添加点击事件,编辑CheckBoxActivity.java

    package com.example.qing.myapplication2;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.widget.CheckBox;
    import android.widget.CompoundButton;
    import android.widget.Toast;
    
    public class CheckBoxActivity extends AppCompatActivity {
    
        private CheckBox mCb5,mCb6;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_check_box);
    
            mCb5 = (CheckBox) findViewById(R.id.cb_5);
            mCb6 = (CheckBox) findViewById(R.id.cb_6);
    
            mCb5.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
                    Toast.makeText(CheckBoxActivity.this,isChecked?"5被选中":"5未被选中",Toast.LENGTH_SHORT).show();
                }
            });
    
            mCb6.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
                    Toast.makeText(CheckBoxActivity.this,isChecked?"6被选中":"6未被选中",Toast.LENGTH_SHORT).show();
                }
            });
        }
    }
    
    

    八. ImageView

    1. 新建EmptyActivity, 命名为ImageViewActivity,系统会自动完成3个任务
    2. 编辑Activity_main.xml,添加一个按钮,并添加点击事件,跳转到新的页面来演示
    3. 编辑activity_image_view.xml, 添加3个ImageView
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.example.qing.myapplication2.ImageViewActivity">
    
        <ImageView
            android:id="@+id/iv_1"
            android:layout_width="300dp"
            android:layout_height="200dp"
            android:background="#FF9900"
            android:src="@drawable/bg_img1"
            android:scaleType="fitXY"
            />
            <!--android:scaleType="fitXY" 设置为拉伸填满-->
            <!--android:scaleType="fitCenter" 设置为拉伸居中,不填满-->
            <!--android:scaleType="centerCrop" 设置为裁剪居中-->
    
        <ImageView
            android:id="@+id/iv_2"
            android:layout_width="300dp"
            android:layout_height="200dp"
            android:background="#FF9900"
            android:src="@drawable/bg_img1"
            android:layout_below="@id/iv_1"
            android:layout_marginTop="10dp"
            android:scaleType="fitCenter"
            />
    
    	<!--这里演示一下加载网络图片-->
        <ImageView
            android:id="@+id/iv_4"
            android:layout_width="300dp"
            android:layout_height="200dp"
            android:background="#FF9900"
            android:layout_below="@id/iv_2"
            android:layout_marginTop="10dp"
            android:scaleType="fitCenter"
            />
    </RelativeLayout>
    
    1. 效果图
      在这里插入图片描述

    2. 为了给ImageView4加载网络上的图片,需要引用github上面的Glide
      我导入失败了,后续更新…
      编辑build.gradle文件,添加代码,可能细微之间还须修改,我出错了很多次才成功的

    //引用图片
    repositories {
        mavenCentral()
       // google()
    }
    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        androidTestCompile('com.android.support.test.espresso:espresso-core:2.0', {
            exclude group: 'com.android.support', module: 'support-annotations'
        })
        compile 'com.android.support:appcompat-v7:25.3.1'
        compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha7'
        testCompile 'junit:junit:4.12'
        compile 'com.android.support:design:25.3.1'
    
        //引用图片
        compile 'com.github.bumptech.glide:glide:4.0.0'
        //compile 'com.android.suppor:support-v4:25.3.1'
        annotationProcessor 'com.github.bumptech.glide:compiler:4.0.0'
    }
    
    1. 编辑ImageViewActivity.java
    package com.example.qing.myapplication2;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.widget.ImageView;
    
    import com.bumptech.glide.Glide;
    
    public class ImageViewActivity extends AppCompatActivity {
    
        private ImageView mIv4;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_image_view);
    
            mIv4 = (ImageView) findViewById(R.id.iv_4);
            //Glide加载网络上的图片到mIv4中去
            Glide.with(this).load("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1547022866640&di=d1dcdffcf4735c63741ac9bbcc8d15d4&imgtype=0&src=http%3A%2F%2Fe.hiphotos.baidu.com%2Fimage%2Fpic%2Fitem%2F83025aafa40f4bfb0f815ad60e4f78f0f63618db.jpg")
                    .into(mIv4);
        }
    }
    
    1. 还需要编辑AndroidManifest.xml添加网络权限
    	<!--加载网络权限,添加在application的前面-->
        <uses-permission android:name="android.permission.INTERNET" />
    
    1. 预览效果
      成功加载网络上的图片

    九.ListView

    先来演示手动创建一个ListViewActivity,不用系统自动生成
    9. java下面新建一个包ListViewActivity,新建一个类ListViewActivity.java继承Activity
    10. 编辑ListViewActivity.java

    package com.example.qing.myapplication2.listViewActivity;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.widget.ListView;
    
    import com.example.qing.myapplication2.R;
    
    
    public class ListViewActivity extends Activity {
    
       private ListView mLv1;
    
       @Override
       protected void onCreate(@Nullable Bundle savedInstanceState) {
           super.onCreate(savedInstanceState);
           setContentView(R.layout.activity_listview);
    
           //获取activity_listview.xml中的ListView,id是lv_1
           mLv1 = (ListView) findViewById(R.id.lv);
           //添加一个自制的监听器
           mLv1.setAdapter(new MyListAdapter(ListViewActivity.this));
       }
    }
    
    
    1. 左侧栏新建一个MyListAdapter.java
    package com.example.qing.myapplication2.listViewActivity;
    
    
    import android.content.Context;
    import android.text.Layout;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.ImageView;
    import android.widget.TextView;
    
    import com.example.qing.myapplication2.R;
    
    public class MyListAdapter extends BaseAdapter {
    
        private Context context;
        private LayoutInflater mLayoutInflater;
    
        MyListAdapter(Context context){
            this.context = context;
            mLayoutInflater = LayoutInflater.from(context);
        }
    
        //设置item的数量
        @Override
        public int getCount() {
            return 20;
        }
    
        @Override
        public Object getItem(int position) {
            return null;
        }
    
        @Override
        public long getItemId(int position) {
            return 0;
        }
    
        //静态类
        static class ViewHolder{
            public ImageView imageView;
            public TextView tvTile,tvTime,tvContent;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
            if(convertView==null){
                convertView = mLayoutInflater.inflate(R.layout.layout_list_item,null);
                holder = new ViewHolder();
                holder.imageView = convertView.findViewById(R.id.iv);
                holder.tvTile = convertView.findViewById(R.id.tv_title);
                holder.tvTime = convertView.findViewById(R.id.tv_time);
                holder.tvContent = convertView.findViewById(R.id.tv_content);
                convertView.setTag(holder);
            }else{
                holder = (ViewHolder) convertView.getTag();
            }
    
            holder.tvTile.setText("这是标题");
            holder.tvTime.setText("2088-08-08");
            holder.tvContent.setText("这是新的内容");
            //Glide
            //Glide.with(mContext).load("https://...").into(mIv4);
            return convertView;
        }
    }
    
    
    1. 左侧栏layout右击,新建一个layout resource file,命名为activity_listview, 这里与上面java代码中R.layout.activity_listview相照应, 编辑 activity_listview.xml
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingLeft="15dp"
        android:paddingRight="15dp"
        android:paddingTop="10dp"
        android:paddingBottom="10dp"
        android:orientation="vertical">
    
        <ListView
            android:id="@+id/lv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            />
            
    </LinearLayout>
    
    1. 左侧栏layout新建一个layout_list_item.xml
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">
    
    
        <ImageView
            android:id="@+id/iv"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:background="#000"
            android:scaleType="centerCrop"
            />
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:paddingLeft="10dp"
            >
            <TextView
                android:id="@+id/tv_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Hello"
                android:textSize="20sp"
                android:textColor="@color/colorBlack"
                />
            <!--android:textColor="@color/colorBlack" 顏色引用values下面的colors.xml中的資源-->
    
            <TextView
                android:id="@+id/tv_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:text="2019-1-8"
                android:textSize="18sp"
                android:textColor="@color/colorGrayDark"
                />
    
            <TextView
                android:id="@+id/tv_content"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="这是内容"
                android:textSize="18sp"
                />
    
        </LinearLayout>
    
    </LinearLayout>
    
    1. 在AndroidManifest.xml中手动声明一下,如果自动创建系统会自动声明
    <activity android:name=".listViewActivity.ListViewActivity"></activity>
    

    或者这样子

    <activity android:name="com.example.qing.myapplication2.listViewActivity.ListViewActivity"></activity>
    
    1. 为每一项添加点击事件, 编辑ListViewActivity.java,在设定自制监听器下面继续添加代码
    //为每一项添加点击事件
            mLv1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    Toast.makeText(ListViewActivity.this,"你点击了第"+position+"项",Toast.LENGTH_SHORT).show();
                    //后面可以添加跳转新页面的事件
                }
            });
    
            //为每一项添加长按事件
            mLv1.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
                @Override
                public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                    Toast.makeText(ListViewActivity.this,"你长按了第"+position+"项",Toast.LENGTH_SHORT).show();
                    //后面还可以添加编辑删除的功能
                    //true表示我已经处理完了,不需要上面的点击事件再来处理一次
                    return true;
                }
            });
    
    1. 效果图
      在这里插入图片描述

    十. GridView

    这个控件与上面的ListView类似
    9. activity_main.xml下面添加一个按钮, 并且MainActivity.java下面添加点击事件,点击跳转到新的演示界面
    10. 左侧栏java下面新建一个包gridView, 下面建立一个类GridViewActivity.java

    package com.example.qing.myapplication2.gridView;
    
    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.support.v7.app.AppCompatActivity;
    import android.widget.GridView;
    
    import com.example.qing.myapplication2.R;
    import com.example.qing.myapplication2.listViewActivity.MyListAdapter;
    
    
    public class GridViewActivity extends AppCompatActivity {
    
        private GridView mGv;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_gridview);
    
            //获取Activity_gridview.xml中的GridView,id是gv
            mGv = (GridView) findViewById(R.id.gv);
            //添加一个自制的监听器
            mGv.setAdapter(new MyGridViewAdapter(GridViewActivity.this));
        }
    }
    
    
    1. layout下面新建一个activity_gridview.xml
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <GridView
            android:id="@+id/gv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:numColumns="3"
            android:horizontalSpacing="10dp"
            android:verticalSpacing="10dp"
            />
        <!--android:numColumns="3" 列数-->
        <!--android:horizontalSpacing="10dp" 水平间距-->
    
    
    </LinearLayout>
    
    1. gridview包下面新建一个类, MyGridViewAdapter.java
    package com.example.qing.myapplication2.gridView;
    
    import android.content.Context;
    import android.text.Layout;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.ImageView;
    import android.widget.TextView;
    
    import com.example.qing.myapplication2.R;
    import com.example.qing.myapplication2.listViewActivity.MyListAdapter;
    
    
    public class MyGridViewAdapter extends BaseAdapter {
    
        private Context mcontext;
        private LayoutInflater mLayoutInflater;
    
        public MyGridViewAdapter(Context context){
            this.mcontext = context;
            mLayoutInflater = LayoutInflater.from(context);
        }
    
        //控制所有的item数量
        @Override
        public int getCount() {
            return 10;
        }
    
        @Override
        public Object getItem(int position) {
            return null;
        }
    
        @Override
        public long getItemId(int position) {
            return 0;
        }
    
        static class ViewHolder{
            public ImageView imageView;
            public TextView textView;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
            if(convertView==null){
                convertView = mLayoutInflater.inflate(R.layout.layout_grid_item,null);
                holder = new ViewHolder();
                holder.imageView = convertView.findViewById(R.id.btn_imageview);
                holder.textView = convertView.findViewById(R.id.tv_title);
                convertView.setTag(holder);
            }else{
                holder = (ViewHolder) convertView.getTag();
            }
            //赋值
            holder.textView.setText("花");
            //Glide
            //Glid.with(mcontext),load("http://...").into(holder.imageView);
            return convertView;
        }
    }
    
    
    1. layout下面新建一个layout_grid_item.xml, 表示每一个item的样子
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="match_parent"
        android:layout_height="match_parent">
    
    
        <ImageView
            android:id="@+id/iv_grid"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:scaleType="fitCenter"
            android:background="@color/colorBlack"
            />
    
        <TextView
            android:id="@+id/tv_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Hello"
            android:textColor="@color/colorAccent"
            android:gravity="center"
            android:layout_marginTop="10dp"
            />
    
    
    </LinearLayout>
    
    1. 在AndroidManifest.xml 里面添加声明
    <activity android:name=".gridView.GridViewActivity"></activity>
    
    1. 最后给每一项添加点击事件,编辑 GridViewActivity.java,代码添加在自制的监听器下面
    
    //添加每一项点击事件
            mGv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    Toast.makeText(GridViewActivity.this,"你点击了第"+position+"项",Toast.LENGTH_SHORT).show();
                }
            });
    
            //添加每一项长按事件
            mGv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
                @Override
                public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                    Toast.makeText(GridViewActivity.this,"你长按第"+position+"项",Toast.LENGTH_SHORT).show();
                    //true表示这件事我处理完了,不需要上面的点击事件再来处理一次
                    return true;
                }
            });
    
    1. 效果图
      在这里插入图片描述

    十一.滚动视图ScrollView
    编辑activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
    
        android:background="#00FF00">
    
        <!--ScrollView 下面只能包含一个子元素,所以要用LinearLayout包含所有的Button-->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            >
    
            <Button
                android:id="@+id/btn_textview"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="TextView"
                android:textAllCaps="false"/>
            <!--android:textAllCaps="false"关闭默认的所有文字大写-->
    
            <Button
                android:id="@+id/btn_button"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Button"
                android:textAllCaps="false"/>
    
            <Button
                android:id="@+id/btn_edittext"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="EditText"
                android:textAllCaps="false"/>
    
            <Button
                android:id="@+id/btn_radiobutton"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="RadioButton"
                android:textAllCaps="false"/>
    
            <Button
                android:id="@+id/btn_checkbox"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="CheckBox"
                android:textAllCaps="false"/>
    
            <Button
                android:id="@+id/btn_imageview"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="imageview"
                android:textAllCaps="false"/>
    
            <Button
                android:id="@+id/btn_listview"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="ListView"
                android:textAllCaps="false"/>
            <!--android:textAllCaps="false"关闭默认的所有文字大写-->
    
            <Button
                android:id="@+id/btn_gridview"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="GridView"
                android:textAllCaps="false"/>
    
            <HorizontalScrollView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">
    
                <!--同样的HorizontalScrollView子元素只能有一个,所以用LinearLayout把所有的Button包起来-->
                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal"
                    >
                    <Button
                        android:layout_width="200dp"
                        android:layout_height="300dp"
                        android:text="text HorizontalScrollView"
                        android:textAllCaps="false"
                        />
                    <Button
                        android:layout_width="200dp"
                        android:layout_height="300dp"
                        android:text="text HorizontalScrollView"
                        android:textAllCaps="false"
                        />
                    <Button
                        android:layout_width="200dp"
                        android:layout_height="300dp"
                        android:text="text HorizontalScrollView"
                        android:textAllCaps="false"
                        />
                    <Button
                        android:layout_width="200dp"
                        android:layout_height="300dp"
                        android:text="text HorizontalScrollView"
                        android:textAllCaps="false"
                        />
                    <Button
                        android:layout_width="200dp"
                        android:layout_height="300dp"
                        android:text="text HorizontalScrollView"
                        android:textAllCaps="false"
                        />
                </LinearLayout>
            </HorizontalScrollView>
    
    
            <!--测试滚动视图-->
            <Button
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="测试滚动视图"
                android:textAllCaps="false"
                android:layout_marginTop="300dp"
                />
        </LinearLayout>
    </ScrollView>
    

    效果图
    在这里插入图片描述

    在这里插入图片描述

    下接博客: https://blog.csdn.net/wang342626/article/details/87917342

    展开全文
  • Android笔记汇总

    千次阅读 2013-02-21 22:28:47
    1,android 关闭进程 若是只有一个单独的Activity的工程,例如Activity A,调用android.app.Activity.finish()的话,并不会关闭该工程,只是使之不处于前台,而被置于后台。参考网上的方法,可以调用 android.os...

    1,android 关闭进程

    若是只有一个单独的Activity的工程,例如Activity A,调用android.app.Activity.finish()的话,并不会关闭该工程,只是使之不处于前台,而被置于后台。参考网上的方法,可以调用   android.os.Process.killProcess(android.os.Process.myPid());这种方法确实的是可以关闭该工程进程的,您可以到应用程序管理里头看看,该工程已不存在于Running中。

    但是若是多个的Activity的工程,例如Activity A---》Activity B,而在Activity B中调用android.os.Process.killProcess(android.os.Process.myPid());这种方法应该只是关闭当前的Activity,接着系统会重构之前的Activity A(记住,这里说的是重构,意思是,并不会调用Activity A 的onRestart(),而是调用OnCreate())


    2, Android开发问题整理

    1、The constructor Intent(new View.OnClickListener(){}, Class<ButtonStudyActivity>) is undefined

    点击按钮,进入另一个activity,问题代码如下

    1. <span style="white-space:pre">      </span>Button btn = (Button)findViewById(R.id.btnMe);  
    2.         btn.setOnClickListener(new OnClickListener(){  
    3.   
    4.             @Override  
    5.             public void onClick(View arg0) {  
    6.                 // TODO Auto-generated method stub  
    7.                 Intent intent = new Intent(this, ButtonStudyActivity.class);  
    8.                 startActivity(intent);  
    9.             }});  

    Intent myIntent = new Intent(this, AuswahlActivity.class);    
    this.startActivity(myIntent); 
    

    这部分代码可能在 OnClickListener 中,所以使用:

    Intent myIntent = new Intent(YouCurrentActivity.this, AuswahlActivity.class);
    YouCurrentActivity.this.startActivity(myIntent); 
    

    原因是,在一个匿名类(你的类是OnClickListener),this通常是指OnClickListener而不是activity。intent的第一个参数是Context(应该是activity),因此导致了出现的错误。


    解决方案一:
    1. Intent intent = new Intent(Activityheihei.this, ButtonStudyActivity.class);  
    解决方案二:
    1. <span style="white-space:pre">      </span>final Intent intent = new Intent(Activityheihei.this, ButtonStudyActivity.class);  
    2.         Button btn = (Button)findViewById(R.id.btnMe);  
    3.         btn.setOnClickListener(new OnClickListener(){  
    4.   
    5.             @Override  
    6.             public void onClick(View arg0) {  
    7.                 // TODO Auto-generated method stub  
    8.                 startActivity(intent);  
    9.             }});  
    解决方案三:
    1. <span style="white-space:pre">      </span>final Intent intent = new Intent(this, ButtonStudyActivity.class);  
    2.         Button btn = (Button)findViewById(R.id.btnMe);  
    3.         btn.setOnClickListener(new OnClickListener(){  
    4.   
    5.             @Override  
    6.             public void onClick(View arg0) {  
    7.                 // TODO Auto-generated method stub  
    8.                 startActivity(intent);  
    9.             }});  

    2、ActivityManager: Warning: Activity not started, its current task has been brought to the front

    Eclipse中,Project->Clean...,然后选中项目,clean一下即可。

    3、E/AndroidRuntime(338): java.lang.IllegalStateException: Could not find a methodonClickBtnManifest(View) in the activity class cn.edu.pku.Activityheihei for onClick handler on view class android.widget.Button with id 'btnmanifest'

    想给Button中加入点击事件

    1. <Button  
    2.     android:id="@+id/btnmanifest"  
    3.     ... ...  
    4.     android:onClick="onClickBtnManifest" />  

    Activity中实现如下

    1. private void onClickBtnManifest() {  
    2.   
    3.     Toast.makeText(Activityheihei.this"button manifest", Toast.LENGTH_SHORT).show();  
    4. }  
    该函数需要加入参数View v,之后还是这个错误。private改为public即可。
    1. <span style="white-space:pre">  </span>public void onClickBtnManifest(View v) {  
    2.   
    3.         Toast.makeText(Activityheihei.this"button manifest", Toast.LENGTH_SHORT).show();  
    4.     }  

    4、Unable to resolve target 'android-5'

    使用高版本的SDK后再导入以前用低版本的project时,会遇到一些兼容性的问题。

    需要将project.properties中的target=android-5改为target=android-7就好了。
    但要注意,也要同步将AndroidManifest.xml中的<uses-sdk android:minSdkVersion="5" />改为<uses-sdk android:minSdkVersion="7" />,否则编译中会警告提示使用的版本过低。

    参考http://blog.sina.com.cn/s/blog_64edd5040100nu0d.html


    android通过USB使用真机调试程序

    我的机子很老,开启个android模拟器都要好几分钟,但幸亏有个android的真机,这样直接在andriod手机上调试也是一个不错的选择。下面我就介绍 一下使用android手机来调试android应用程序所需要的步骤:(典型的Hello World程序)

    1、手机通过数据线连接在电脑上

    2、设置android手机为USB调试模式。步骤: menu—> 设置 —> 应用程序 —> 开发 , 选择【USB调试】

    3、如果是window系统,系统会提示安装驱动:

    选择正确的android sdk安装目录,然后点击下一步,系统就开始安装驱动了

    4、驱动安装完成之后,重启电脑(通常系统会有“安装新驱动,重启才能生效”的提示),这但应该明白吧

    5、重复第1步和第2步,打开命令窗口,检测手机设备是否已经被识别,如下所示:

    “HT99YLG11834 device”就是检测到得手机设备

    6、接下来就开始在eclipse上调试android程序了,右击android工程->Run as->Android Application,弹出如下窗口:(重新启动系统之后才有这样的效果)

    7、选中手机设备,点击OK之后,程序就开始在真机上安装了,控制台输出如下信息:

    [2011-04-07 22:24:49 - HelloWorld] Uploading HelloWorld.apk onto device ‘HT99YLG11834′
    [2011-04-07 22:24:49 - HelloWorld] Installing HelloWorld.apk…
    [2011-04-07 22:24:53 - HelloWorld] Success!
    [2011-04-07 22:24:53 - HelloWorld] Starting activity com.eightqiu.activity.StatsResultActivity on device
    [2011-04-07 22:24:57 - HelloWorld] ActivityManager: Starting: Intent {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER]cmp=com.eightqiu.activity/.StatsResultActivity }
    8、运行这个应用程序,这样就可以使用手机来测试了


    3, Android开发真机测试方法

    方法如下:

    (1)开机一部Android手机(当让Pad也行)

    (2)在手机中:设置-->应用程序-->开发-->USB调试

    (3)插上USB

    (4)在CMD中测试一下,连接是否正常,CMD中命令如下:

               adb devices   回车

              若显示你的设备名,则证明连接正常。

    (4)改写AndroidManifest.xml

                  <application
                      android:icon="@drawable/ic_launcher"
                      android:label="@string/app_name" 
                      android:debuggable="true">

             注意:加的是绿的这句。

    (5)执行真机调试操作:

              在Eclipse中右键项目-->Debug As-->Debug Configurations-->Target选项卡-->选择Manual

                                                  -->点击下面Debug-->选择你的设备-->OK

               这时你的设备就会开始执行你的Android程序啦!很流畅。

               下次再想调试时,可以点击Run然后选择你的设备,然后OK,就可以啦。

    (6)注意:无论是否用Eclipse

                         任何Android软件只要在真机上运行发生异常,都可以在命令行窗口下查看具体的异常

                         在CMD中输入:adb logc at    回车

                         注意查看以Causeby开头的行,这些行指明了在哪行代码出错了.........................


    4、Android Activity去除标题栏和状态栏

    一、在代码中设置 

    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    //去除title  
    requestWindowFeature(Window.FEATURE_NO_TITLE);  
    //去掉Activity上面的状态栏 
    getWindow().setFlags(WindowManager.LayoutParams. FLAG_FULLSCREEN , WindowManager.LayoutParams. FLAG_FULLSCREEN); 
       setContentView(R.layout.main); 


    或者 

    requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); 
    getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title_1); 

    R.layout.custom_title_1  这个就是你的标题文件布局 

    二、在配置文件里修改 

    (关键代码:android:theme="@android:style/Theme.NoTitleBar.Fullscreen",如果想只是去除标题栏就后面不用加Fullscreen了,另外,如果想要整个应用都去除标题栏和状态栏,就把这句代码加到<application。。标签里面,如果只是想某个activity起作用,这句代码就加到相应的activity上): 

    隐藏标题栏需要使用预定义样式:android:theme=”@android:style/Theme.NoTitleBar”. 

    隐藏状态栏:android:theme=”@android:style/Theme.NoTitleBar.Fullscreen”. 
    在这里我还想说明一下,用前者在我们应用运行后,会看到短暂的状态栏,然后才全屏,而第二种方法是不会有这种情况的,所以我建议大家使用后者!

    Android Activity去除标题栏和状态栏

    最简单的方法是在配置文件(AndroidManifest.xml)里修改

    Xml代码  收藏代码
    1. android:theme="@android:style/Theme.NoTitleBar.Fullscreen"   

    注意:

    1. 如果想只是去除标题栏就后面不用加Fullscreen了。
    2. 如果想要整个应用都去除标题栏和状态栏,就把这句代码加到<application>标签里面。
    3. 如果只是想某个activity起作用,这句代码就加到相应的<activity>标签上。

    Android去掉标题栏和全屏都是件很容易的事情,最常见的有两种方法:

    第一:在程序代码中实现
    Java代码this.requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏

    this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//去掉信息栏

    this.requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏

    this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//去掉信息栏
    注意:这两行代码要写在页面显示之前,即setContentView(R.layout.XXX)之前
    第二:在AndroidManifest.xml配置文件中实现标签android:theme
    Java代码<activity android:name="Activity1"

    android:theme="@android:style/Theme.NoTitleBar.Fullscreen"></activity>

    <activity android:name="Activity1"

    android:theme="@android:style/Theme.NoTitleBar.Fullscreen"></activity>
    注意:如果不需要全屏,只需要写成android:theme="@android:style/Theme.NoTitleBar即可
    总结:二者的区别
    如果使用第一种方法,在Activity启动时会有短暂的标题栏和信息栏的出现,随后会消失。
    使用第二种方法这不会出现这种情况,个人推荐使用第二种方式,看起来比较流畅。

    Android Activity 常用功能设置(全屏、横竖屏等)

    Activity全屏设置

    方式1:AndroidManifest.xml

    <activity android:name="myAcitivty"  android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />

    方式2:代码实现

    requestWindowFeature(Window.FEATURE_NO_TITLE);  // 隐藏标题栏

    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);  // 隐藏状态栏

    注意:设置全屏的俩段代码必须在setContentView(R.layout.main) 之前,不然会报错。


    Activity横竖屏设置

    方式1:AndroidManifest.xml

    <activity android:name="myAcitivty"  android:screenOrientation="landscape" /> // 或者 “portrait

    方式2:代码实现

    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

    获取横屏方向

    int orientation = this.getResources().getConfiguration().orientation;

    orientation 的常用取值可以为 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE(横屏) 或 ActivityInfo.SCREEN_ORIENTATION_PORTRAIT(竖屏)


    Activity屏幕一直显示

    1:AndroidManifest.xml添加权限

    <uses-permission android:name="android.permission.WAKE_LOCK" />

    2:代码实现

    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);


    android中获得屏幕、视图、任务栏、状态栏的高宽以及屏幕的设置

    首先,有一点需要声明,其实在android中,画布Canvas的高宽其实是屏幕的高宽。

    如此一来,获得屏幕高宽的方法就很多了:

    1.

    Java代码 复制代码
    1. WindowManager windowManager = getWindowManager();   
    2.   
    3. Display display = windowManager.getDefaultDisplay();   
    4.   
    5. screenWidth = display.getWidth();   
    6.   
    7. screenHeight = display.getHeight();  
    1. WindowManager windowManager = getWindowManager();  
    2.   
    3. Display display = windowManager.getDefaultDisplay();  
    4.   
    5. screenWidth = display.getWidth();  
    6.   
    7. screenHeight = display.getHeight();  



    2.

    Java代码 复制代码
    1. DisplayMetrics dm = new DisplayMetrics();   
    2.   
    3. this.getWindowManager().getDefaultDisplay().getMetrics(dm);//this指当前activity  
    4.   
    5. screenWidth =dm.widthPixels;   
    6.   
    7. screenHeight =dm.heightPixels;  
    1. DisplayMetrics dm = new DisplayMetrics();  
    2.   
    3. this.getWindowManager().getDefaultDisplay().getMetrics(dm);//this指当前activity  
    4.   
    5. screenWidth =dm.widthPixels;  
    6.   
    7. screenHeight =dm.heightPixels;  

    以上两种方法在屏幕未显示的时候,还是处于0的状态,即要在setContentView调用之后才有效。

    3.

    还可以在onDraw中由canvas来获得

    Java代码 复制代码
    1. screenWidth =canvas.getWidth();   
    2.   
    3. screenHeight =canvas.getHeight();  
    1. screenWidth =canvas.getWidth();  
    2.   
    3. screenHeight =canvas.getHeight();  



    而视图的高宽则是大多数人所认为的canvas的高宽,其实他所指的是除了任务栏和状态栏的高宽,主要有如下方法:

    1.

    Java代码 复制代码
    1. viewWidth=this.getWidth();   
    2.   
    3. viewHeight=this.getHeight();  
    1. viewWidth=this.getWidth();  
    2.   
    3. viewHeight=this.getHeight();  



    2.重写view的onSizeChanged,该方法会在onCreate之后,onDraw之前调用

    Java代码 复制代码
    1. protected void onSizeChanged(int w, int h, int oldw, int oldh) {   
    2. viewHeight=h;   
    3. viewWidth=w;   
    4. super.onSizeChanged(w, h, oldw, oldh);   
    5. }  
    1. protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
    2. viewHeight=h;  
    3. viewWidth=w;  
    4. super.onSizeChanged(w, h, oldw, oldh);  
    5. }  

    任务栏、状态栏的高宽的高宽我目前还不清楚,不过从网上查找可知:

    引用
    frameworks/core/res/values/themes.xml
    <item name="windowTitleSize">25dip</item>
    frameworks/core/res/values/dimens.xml
    <dimen name="status_bar_height">25dip</dimen>

    在一个activity中如果要获取高宽,最好是放在onSizeChanged中比较保险。

    以上是我对android获得高宽的一点总结,如果有错误的地方,欢迎留言探讨。

    另外,还有对屏幕显示的一些设置:

    //设置为无标题

    Java代码 复制代码
    1. requestWindowFeature(Window.FEATURE_NO_TITLE);  
    1. requestWindowFeature(Window.FEATURE_NO_TITLE);  



    //设置为全屏模式getWindow().setFlags

    Java代码 复制代码
    1. getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);  
    1. getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);  



    //设置为横屏

    Java代码 复制代码
    1. setRequesteOrientation(ActivityInfo.SCREEN_ORIENTATION_LADSCAPE);  

    转自 http://yuyanshan.javaeye.com/blog/750043

    //设置窗体全屏

    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

     

    //设置窗体始终点亮

    getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,

          WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

     

    //设置窗体背景模糊

    getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,
                    WindowManager.LayoutParams.FLAG_BLUR_BEHIND);

    设置Activity的背景颜色

     

    前提是需要在value目录下的string.xml文件中加入一段代码:

     

    Xml代码  收藏代码
    1. <drawable name="bkcolor">#ff00ff</drawable>  

     

     

     

    其中的颜色值可以自己设置。

     

    以下为两种方法:

    一.从代码中设置

    1.首先导入必要的包:

    Java代码  收藏代码
    1. import android.content.res.Resources;  
    2. import android.graphics.drawable.Drawable;  

     

     

    2.然后在onCreate()函数中加入以下代码:

    Java代码  收藏代码
    1. Resources res = getResources();  
    2. Drawable drawable = res.getDrawable(R.drawable.bkcolor);  
    3. this.getWindow().setBackgroundDrawable(drawable);  

      

    二.从布局文件(例如main.xml)中设置

    在<...layout>标签中加上以下代码

    Xml代码  收藏代码
    1. android:background="@drawable/bkcolor"

    Android自适应屏幕方向、大小和分辨率

    Android自适应屏幕方向、大小和分辨率

    屏幕大小

    1、不同的layout

          Android手机屏幕大小不一,有480x320,640x360,800x480.怎样才能让App自动适应不同的屏幕呢? 其实很简单,只需要在res目录下创建不同的layout文件夹,比如:layout-640x360,layout-800x480,所有的layout文件在编译之后都会写入R.java里,而系统会根据屏幕的大小自己选择合适的layout进行使用。

    2、hdpi、mdpi、ldpi

          前的版本中,只有一个drawable,而2.1版本中有drawable-mdpi、drawable-ldpi、drawable-hdpi三个,这三个主要是为了支持多分辨率。

    drawable- hdpi、drawable- mdpi、drawable-ldpi的区别:

    1. drawable-hdpi里面存放高分辨率的图片,如WVGA (480x800),FWVGA (480x854)
    2. drawable-mdpi里面存放中等分辨率的图片,如HVGA (320x480)
    3. drawable-ldpi里面存放低分辨率的图片,如QVGA (240x320)

    系统会根据机器的分辨率来分别到这几个文件夹里面去找对应的图片。在开发程序时为了兼容不同平台不同屏幕,建议各自文件夹根据需求均存放不同版本图片。

    屏幕方向

    1、横屏竖屏自动切换

          可以在res目录下建立layout-port和layout-land两个目录,里面分别放置竖屏和横屏两种布局文件,这样在手机屏幕方向变化的时候系统会自动调用相应的布局文件,避免一种布局文件无法满足两种屏幕显示的问题。

    2、禁用自动切换

    只需要在AndroidManifest.xml文件中加入android:screenOrientation属性限制。

    限制此页面横屏显示

    Xml代码  收藏代码
    1. Android:screenOrientation="landscape"  
    Xml代码  收藏代码
    1.   

     

     

    限制此页面数竖屏显示

    Xml代码  收藏代码
    1. Android:screenOrientation="portrait"   

     

     

     

     

    字体自适应大小

    方法1:

    首先根据不同分辨率获取不同字体大小。 
    在RES里创建
    values-480x320/strings.xml 里面设置

    Xml代码  收藏代码
    1. <dimen name="Text_size">30px</dimen>  

     和 
    values-800x400/strings.xml 里面设置

    Xml代码  收藏代码
    1. <dimen name="Text_size">40px</dimen>   

     

     

    分别代表480X320 和 800X400分辨率情况下 字号为30px和40px;

     

    在java文件中这样调用

    Java代码  收藏代码
    1. <strong>int sizeOfText = (intthis.getResources().getDimension(R.dimen.Text_size);</strong>  

     

    方法2:

    在视图的onsizechanged里获取视图宽度,一般情况下默认宽度是320,所以计算一个缩放比率rate = (float) w/320   (w是实际宽度)
    然后在设置字体尺寸时 paint.setTextSize((int)(8*rate));   (8是在分辨率宽为320 下需要设置的字体大小实际字体大小 = 默认字体大小 x  rate)



    6,设置主Activity.

    主Activity必须在manifest文件中使用<intent-filter>标签,并包含MAIN action和LAUNCHER 内容。例如:

    1. <activity android:name"@string/app_name">
    2. <intent-filter>
    3. <action android:name="android.intent.action.MAIN" />
    4. <category android:name="android.intent.category.LAUNCHER" />
    5. </intent-filter>
    6. </activity>

    注: 当你创建一个新的Android项目,默认的项目会包含一个Activity类,并且此类会有如上的声明。

    如果任何一个activity声明都不包含android.intent.action.MAINandroid.intent.category.LAUNCHER,那么您的应用程序的图标就不会出现在android的主屏菜单列表上了。.


    7,销毁Activity的特例

    注意 :一般来说,系统会在调用onPause()方法和onStop()之后才调用onDestory()方法,但是,有一种情况是例外的,那就是在你在onCreate()方法中调用finish()方法。在一些情况下,你的Activity作为一个临时决定的操作对象而去启动另外一个Activity时,你可能需要在onCreate()方法中调用finish()方法去销毁Activity,在这种情况中,系统会直接调用onDestroy()方法而不用再去调用其他的生命周期函数。

    Android结束Activity退出程序的一种有效方法

    关于完全退出Android程序,网上这方面的帖子很多,方法也很多。记得当时自己写的第一个比较完整的项目的时候就遇上了这个问题,由于对Activity的生命周期了解不够,又使用了TabActivity使得层次关系比较复杂,在程序中添加的“退出”菜单项经常无法完全退出,之后网上各种搜索,各种方法也试过了,什么System.exit(0)啊,结束进程之类的啊,都依然无效果。

    后面才发现的这个方法。思路也很简单,回想自己当初为了解决这个问题时的苦苦寻觅,遂决定将其共享,供遇到此问题人士作为参考。

     

    啰嗦够了,上思路:添加一个全局变量作为程序退出的标记(boolean类型),当需要退出程序时置为true,程序中每个Activity的onStart方法中对该变量进行判断,为true就结束自己。

    看代码吧:

    使用Application来保存一个全局变量isProgramExit。(对Application使用不熟悉的话查看相关资料)

    复制代码
    public class MyApplication extendsApplication {
    
    // 程序退出标记
    
    private static boolean isProgramExit = false;
    
    public void setExit(booleanexit) {
    
    isProgramExit= exit;
    
    }
    
    public booleanisExit() {
    
    return isProgramExit;
    
    }
    
    }
    复制代码

     

     

    在你退出时需要结束的每个Activity的 onStart方法加上以下代码:

    复制代码
    protected voidonStart() {
    
    super.onStart();
    
    MyApplication mApp = (MyApplication)getApplication();
    
    if(mApp.isExit()) {
    
    finish();
    
    }
    
    }
    复制代码

     

    比如,程序中有三个Activity,A —— B —— C;现在在C中有个按钮,点击退出整个程序。按照上面说的,在A和B的onStart方法中加入判断代码(C中可以不加),C中点击按钮时执行:

    MyApplication mApp = (MyApplication)getApplication();
    
    mApp.setExit(true);
    
    finish();

     

    这样C结束了自己,按照流程会回到B,然后B中会进行判断,因为退出条件满足,结束自己;再回到A,同样也结束……

     

    可以看到,这种方法并不高明,甚至有些复杂,因为要在每个Activity的onStart中都加上判断。但不可否认的是这种方法却是绝对有效的,不管你的程序中Activity如何跳转来跳转去,只要一声令下,通通结束,屡试不爽。

    所以,有遇到程序退出问题的朋友可以作为参考。

    感觉这个方法似乎还存在些问题吧。如果直接这样写,那么虽然退出了程序,但是这只是让程序变成了空进程,如果这个时候再点击程序,那么Application中的全局变量应该还是有效的,这样将导致程序在启动的时候就直接退出。应该在activity的oncreate方法中重新设置这个值吧,但是这样会有一个潜在的问题,比如我们从启动的activity是A-B-C,那么这样栈里就依次存放着A,B,C, 如果此时由于某种原因导致A被销毁了(这种情况应该是存在的, onSaveInstanceStatus方法就是针对这种情况吧),那么这是用这个方法退出的话,当取得栈中A的时候,由于A被销毁了,这是会调用A的oncreate方法,而oncreate方法中如果又重新设置了全局变量的值,这时就不能正常退出了。 所以是不是需要在onSaveInstanceStatus这个方法里做一些特殊处理?

    动态的修改自定义custom title


    在android中 getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.text_title);     使用上面的话时 他所产生的并不是把以前的用现在的替换只是用   R.layout.text_title放在了默认样式的上面,如果你想通过一个按钮修改标题
    以及view上的消息有两种方法:
    private void setCustomTitleFeatureInt(int value) {  
           try {        // retrieve value for com.android.internal.R.id.title_container(=0x1020149)      
             int titleContainerId = (Integer) Class.forName(               
             "com.android.internal.R$id").getField("title_container").get(null);       
             // remove all views from titleContainer     
               ((ViewGroup) getWindow().findViewById(titleContainerId)).removeAllViews();     
                 // add new custom title view       
                  getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, value);
                      } catch(Exception ex) {       
                      // whatever you want to do here..    }
                      }

    这种方法是取消以前的 不过这种方法可靠性不好
    2.你可以用隐藏的方式:
    findViewById(R.id.custom_title_1).setVisibility(View.GONE);getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title_2);


    1.得到屏幕的screen dimensions
    Display display = getWindowManager().getDefaultDisplay();
    int width = display.getWidth();int height = display.getHeight();

    2. 播放 gif图片在android
    @Override protected void onDraw(Canvas canvas) {          
    canvas.drawColor(0xFFCCCCCC);                      
      Paint p = new Paint();           
      p.setAntiAlias(true);         
         
         canvas.drawBitmap(mBitmap4, 210, 170, null);           
         mDrawable.draw(canvas);           
         long now = android.os.SystemClock.uptimeMillis();          
          if (mMovieStart == 0) {   // first time                mMovieStart = now;            }           
          if (mMovie != null) {               
            int dur = mMovie.duration();               
               if (dur == 0) {                   
                  dur = 1000;                }               
                  int relTime = (int)((now - mMovieStart) % dur);               
                  mMovie.setTime(relTime);             
                    mMovie.draw(canvas, getWidth() - mMovie.width(),                         
                      getHeight() - mMovie.height());              
                       invalidate();           
                       }      
                        }
    http://developer.android.com/guide/samples/ApiDemos/src/com/example/android/apis/graphics/BitmapDecode.html
    @Override
                        protected void onDraw(Canvas canvas) {
                            if(movie != null) {
                                    long now = android.os.SystemClock.uptimeMillis();
                                            int dur = Math.max(movie.duration(), 1);
                                            // is it really animated?       
                                            int pos = (int)(now % dur);       
                                            movie.setTime(pos);       
                                            movie.draw(canvas, x, y);
                                             invalidate();   
                                     }}

    4. 打开sd卡中的sqllite
    File dbfile = new File("/sdcard/mydb.sqlite" );
                                      SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbfile, null);

    5.得到手机的IMEI
    ((TelephonyManager) getSystemService=(Context.TELEPHONY_SERVICE)).getDeviceId();

    6. 不让程序 生成一个appliation 去掉
    <category android:name="android.intent.category.LAUNCHER" />
    当然你的让你的程序 被引导启动

    7.使用appliation 的id 可以获得不同appliation的数据:
    android:sharedUserId="string" 在主xml中添加上面一句话,然后签名也要一样 两个app的id也要设置成一样 如都是string 那么这两个程序就可以相互访问彼此的数据,也可以在同一个process中了
    8.判断相机设备存在不
    private android.hardware.Camera mCameraDevice;
    try { 
        mCameraDevice = android.hardware.Camera.open();}
    catch (RuntimeException e) {  Log.e(TAG, "fail to connect Camera", e);

    9使listView 透明
    android:background="#00000000"
    android:cacheColorHint="#00000000"
    或者
    android:background="@android:color/transparent"

    •The background android screen image should be visible.
    屏幕的背景图像可以看见
    manifest file 添加attribute 到 activity.
    android:theme="@android:style/Theme.Dialog"


    Android开发:定制Activity的标题栏(Titlebar)

    缺省的情况下,通常见到Activity的标题栏(Titlebar)是这样的(红色框内):


    HandleContacts是Activity的标题。

    有时候,我们希望能改变一下这样单调的状况。比如,要在标题栏中增加一个用于美化界面的图标、增一个输入框或按钮之类的,怎样才能做到这一点呢?我们不妨来看一个实际的例子。

    1.    首先如下创建一个Android项目

     

    2.    将图片magnifier.png拖入该项目的res/drawable-mdpi文件夹下。magnifier.png图片的样子是这样的:


    3.    在该项目的res/layout文件夹下,创建一个布局titlebar.xml,这个布局将用于定制Activity的标题栏

    编辑titlebar.xml,使其内容如下:

    <?xmlversion="1.0" encoding="utf-8"?>

    <LinearLayout

           xmlns:Android="http://schemas.android.com/apk/res/android"

           android:orientation="horizontal"

           android:layout_width="fill_parent"

           android:layout_height="wrap_content">

          

           <ImageView

                    android:layout_width="wrap_content"

                    android:layout_height="wrap_content"

                    android:src="@drawable/magnifier"

                    android:gravity="bottom"

           />

           <TextView

                     android:layout_width="wrap_content"

                     android:layout_height="38dip"

                     android:text="@string/app_name"

                     android:textColor="#FFFFFFFF"

                     android:textSize="14dip"

                     android:paddingTop="1dip"

           />

          

           <EditText

                       android:id="@+id/searchparameter"

                       android:layout_width="wrap_content"

                       android:layout_height="38dip"

                       android:text="ABCDEFGHIJ"

                       android:textSize="14dip"

                       android:layout_margin="1dip"

             />

            

             <Button android:id="@+id/button"

                       android:layout_width="wrap_content"

                       android:layout_height="38dip"

                       android:text="OK"

                       android:textSize="14dip"

             />

    </LinearLayout>

     

    在上面的LinearLayout中,增加了以下控件:

    一个ImageView,用于显示一个图标

    一个TextView,用于显示应用的名称

    一个EditText,用于接收输入

    一个Button,用于测试

     

    4.    修改CustomizeTitlebar.java,使之如下:

    public class CustomizeTitlebar extends Activity

    {

        @Override

        public void onCreate(Bundle savedInstanceState)

        {

           super.onCreate(savedInstanceState);

           requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);

           setContentView(R.layout.main);

           getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.titlebar);

        }

    }

    以上加粗的两行很重要,而且必须要严格按照上面那样的顺序出现在代码中。即:

    requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);必须出现在super.onCreate(savedInstanceState);之后,setContentView(R.layout.main);之前。其意思就是告诉系统,本程序要自己定义Titlebar;

    getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,R.layout.titlebar); 则必须出现在setContentView之后,其意思就是告诉系统,自定义的布局是R.layout.titlebar(即,我们前面编写的titlebar.xml)

    到这里,不妨来运行一下,看看结果如何:


    我们看到,Titlebar基本上按照我们的意思进行了改变,但也存在着一个缺陷:Titlebar太窄了,那么怎样改变Titlebar的高度呢?

    5.    要改变Titlebar的高度,我们得先创建styles.xml:


    编辑styles.xml,使其内容如下:

    <?xmlversion="1.0" encoding="utf-8"?>

    <resources>

             <style name="titlebarstyle"parent="Android:Theme">

                       <item name="android:windowTitleSize">38dip</item>

             </style>

    </resources>

    上面<item name="android:windowTitleSize">39dip</item>这一句,就是用来设定Titlebar的高度的。

     

    6.    在上面的基础上,我们需要修改AndroidManifest.xml中,相应Activity的属性。如下:

    <?xmlversion="1.0" encoding="utf-8"?>

    <manifestxmlns:android="http://schemas.android.com/apk/res/android"

          package="com.pat.customizetitlebar"

          android:versionCode="1"

          android:versionName="1.0">

        <application android:icon="@drawable/icon"android:label="@string/app_name">

            <activity android:name=".CustomizeTitlebar"

                      android:label="@string/app_name"

                      android:theme="@style/titlebarstyle">

                <intent-filter>

                    <action android:name="android.intent.action.MAIN"/>

                    <category android:name="android.intent.category.LAUNCHER"/>

                </intent-filter>

            </activity>

     

        </application>

        <uses-sdk android:minSdkVersion="8"/>

     

    </manifest>

    注意粗体字是新增上去的,其中的titlebar是在第5步中增加的。现在来看看运行结果:

     

    可以看到结果完全符合了我们的要求。

     

    7.    我们还可以改变Titlebar的背景颜色。为此我们修改前面的styles.xml,使之如下:

    <?xml version="1.0" encoding="utf-8"?>

    <resources>

    <style name="CustomizedWindowTitleBackgroundColor">

               <item name="android:background">#047BF0</item>

    </style>

    <style name="titlebarstyle" parent="android:Theme">

               <item name="android:windowTitleSize">38dip</item>

               <item name="android:windowTitleBackgroundStyle">@style/CustomizedWindowTitleBackgroundColor</item>

    </style>

    </resources>

    注意,其中的粗体字是新增加的。

    项目其他文件,均无需变动。运行结果如下:

     

    8.    最后,我们以OK按钮为例来测试Titlebar上的控件的事件响应。为此,修改CustomizeTitlebar.java,使之如下:

    public class CustomizeTitlebar extends Activity

    implements

    OnClickListener

    {

       private Button button;

        @Override

        public void onCreate(Bundle savedInstanceState)

        {

           super.onCreate(savedInstanceState);

           requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);

           setContentView(R.layout.main);

           getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.titlebar);

           

            button = (Button)findViewById(R.id.button);

            button.setOnClickListener(this);

        }

       

      public voidonClick(View v)

      {

               if(v.getId() == R.id.button)

               {

                        Toast.makeText(this, "OK button in Titlebar clicked...", Toast.LENGTH_LONG).show();

               }

       }

    }

    粗体字部分是新增加的代码。重新运行本项目,等界面出来后,点击Titlebar上的OK按钮,将出现:


    这说明,Titlebar上自己增加上去的控件,可以很好地响应相关的事件。





    Android 应用程序窗体显示状态操作(requestWindowFeature()的应用)

    我们在开发程序是经常会需要软件全屏显示、自定义标题(使用按钮等控件)和其他的需求,今天这一讲就是如何控制Android应用程序的窗体显示.

      首先介绍一个重要方法那就是requestWindowFeature(featrueId),它的功能是启用窗体的扩展特性。参数是Window类中定义的常量。

    一、枚举常量

    1.DEFAULT_FEATURES:系统默认状态,一般不需要指定

    2.FEATURE_CONTEXT_MENU:启用ContextMenu,默认该项已启用,一般无需指定

    3.FEATURE_CUSTOM_TITLE:自定义标题。当需要自定义标题时必须指定。如:标题是一个按钮时

    4.FEATURE_INDETERMINATE_PROGRESS:不确定的进度

    5.FEATURE_LEFT_ICON:标题栏左侧的图标

    6.FEATURE_NO_TITLE:吴标题

    7.FEATURE_OPTIONS_PANEL:启用“选项面板”功能,默认已启用。

    8.FEATURE_PROGRESS:进度指示器功能

    9.FEATURE_RIGHT_ICON:标题栏右侧的图标

     

    二、详解

    默认显示状态

    图1默认

    1.FEATURE_CUSTOM_TITLE详解

    this.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
            setContentView(R.layout.main);

     

    图2 无标题

     

    这是因为没设置Featrue

    在上面代码后加:getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title); 

     

    图3自定义标题

    自定义标题完成,它是一个xml文件布局

    title.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content" >
     
      <ImageView android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:src="@drawable/icon"/>
       <TextView android:id="@+id/text" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:layout_alignParentLeft="true" 
            android:text="文本" /> 
     
    </LinearLayout>

    3.FEATURE_INDETERMINATE_PROGRESS详解

    表示一个进程正在运行

        图4标题进度条显示

    实现代码

    1.progress.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content">
      <ProgressBar android:id="@+id/progress"

          android:layout_width="wrap_content"

          android:layout_height="wrap_content"   

          android:layout_gravity="center_vertical"
          style="?android:attr/progressBarStyleSmallTitle">

    </ProgressBar>
    </LinearLayout>

     

    2.Java代码

    this.requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
      setContentView(R.layout.main);


      getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS, R.layout.progress);
      setProgressBarIndeterminateVisibility(true);

      

    3.FEATURE_LEFT_ICON详解

    左侧显示图标

    图5

     

    实现代码


      this.requestWindowFeature(Window.FEATURE_LEFT_ICON);
      setContentView(R.layout.main);
      
      getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, R.drawable.icon);

     

    4.FEATURE_NO_TITLE详解

     可用于全屏显示

     

    实现代码

    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
      setContentView(R.layout.main);
     
      getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

     

    图6全屏显示

     



    android开发中经常会在setContentView(R.layout.XXX); 前设置requestWindowFeature(XXXX)。

    他的意思是需要软件全屏显示、自定义标题(使用按钮等控件)和其他的需求

    首先介绍一个重要方法那就是requestWindowFeature(featrueId),它的功能是启用窗体的扩展特性。参数是Window类中定义的常量。

    一、枚举常量

    1.DEFAULT_FEATURES:系统默认状态,一般不需要指定

    2.FEATURE_CONTEXT_MENU:启用ContextMenu,默认该项已启用,一般无需指定

    3.FEATURE_CUSTOM_TITLE:自定义标题。当需要自定义标题时必须指定。如:标题是一个按钮时

    4.FEATURE_INDETERMINATE_PROGRESS:不确定的进度

    5.FEATURE_LEFT_ICON:标题栏左侧的图标

    6.FEATURE_NO_TITLE:没有标题

    7.FEATURE_OPTIONS_PANEL:启用“选项面板”功能,默认已启用。

    8.FEATURE_PROGRESS:进度指示器功能

    9.FEATURE_RIGHT_ICON:标题栏右侧的图标

    二、详解

    默认显示状态

     

    1.FEATURE_CUSTOM_TITLE详解

    Java代码  收藏代码
    1. this.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);  
    2. setContentView(R.layout.main);  
     

    这是因为没有设置Featrue

    在上面代码后加:getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title);

     

    自定义标题完成,它是一个xml文件布局

     

    Xml代码  收藏代码
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     android:layout_width="wrap_content"  
    4.     android:layout_height="wrap_content" >  
    5.   
    6.     <ImageView  
    7.         android:layout_width="wrap_content"  
    8.         android:layout_height="wrap_content"  
    9.         android:src="@drawable/ic_launcher"  
    10.         />  
    11.   
    12.     <TextView  
    13.         android:id="@+id/text"  
    14.         android:layout_width="wrap_content"  
    15.         android:layout_height="wrap_content"  
    16.         android:layout_alignParentLeft="true"  
    17.         android:textColor="#000000"  
    18.         android:text="FEATURE_CUSTOM_TITLE" />  
    19.   
    20. </LinearLayout>  
     

     

    2.FEATURE_INDETERMINATE_PROGRESS详解

    可以用来表示一个进程正在运行

    Java代码  收藏代码
    1. this.requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);  
    2. setContentView(R.layout.main);  
    3. getWindow().setFeatureInt(Window.FEATURE_INDETERMINATE_PROGRESS, R.layout.progress);  
    4. setProgressBarIndeterminateVisibility(true);  
     
    Xml代码  收藏代码
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     android:layout_width="wrap_content"  
    4.     android:layout_height="wrap_content" >  
    5.   
    6.     <ProgressBar  
    7.         android:id="@+id/progress"  
    8.         style="?android:attr/progressBarStyleSmallTitle"  
    9.         android:layout_width="wrap_content"  
    10.         android:layout_height="wrap_content"  
    11.         android:layout_gravity="center_vertical" >  
    12.     </ProgressBar>  
    13.   
    14. </LinearLayout>  
      

    3.FEATURE_LEFT_ICON和FEATURE_RIGHT_ICON详解

    Java代码  收藏代码
    1. requestWindowFeature(Window.FEATURE_RIGHT_ICON);  
    2. setContentView(R.layout.main);      
    3. getWindow().setFeatureDrawableResource(Window.FEATURE_RIGHT_ICON,R.drawable.ic_launcher);  
     
    Java代码  收藏代码
    1. requestWindowFeature(Window.FEATURE_LEFT_ICON);  
    2. setContentView(R.layout.main);          
    3. getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,R.drawable.ic_launcher);  
     

     

     4.FEATURE_NO_TITLE详解

    Java代码  收藏代码
    1. this.requestWindowFeature(Window.FEATURE_NO_TITLE);  
    2. setContentView(R.layout.main);  
     
    Java代码  收藏代码
    1. getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);  
     

    Manifast.xml中的属性 理解

    <!-- android:screenOrientation="" 固定屏幕显示模式,portrait表示横向,landscape表示纵向  -->
            <!-- android:theme="@style/Sub" 设置activity的样式 -->

    1. <activity     android:name=".Test"  android:theme="@style/Sub" android:screenOrientation="portrait"></activity>  

    values文件夹下的themes.xml文件中

    1. <style name="SubTitleBackground">   
    2.         <item name="android:background">#BA3A37</item>   
    3.     </style>  
    4.       
    5.     <style name="Sub" parent="android:Theme">   
    6.         <item name="android:windowTitleSize">40dp</item>   
    7.         <item name="android:windowTitleBackgroundStyle">@style/SubTitleBackground</item>  
    8.         <item name="android:windowBackground">#E88024</item>  
    9.     </style> 

    android退出整个程序

    1. public boolean onKeyDown(int keyCode, KeyEvent event) {  
    2.         // 当点击返回按钮时,退出程序  
    3.         if (keyCode == KeyEvent.KEYCODE_BACK) {  
    4.             android.os.Process.killProcess(android.os.Process.myPid());  
    5.         }  
    6.         return super.onKeyDown(keyCode, event);  
    7.     } 

    Android释放内存(结束进程)  

    2012-06-06 22:04:46|  分类:Android|字号 订阅

    这两天在搞个内存清理小插件,网上很少这方面资料,之前找过清理缓存的例子测试,结果不成功。后来自己思考该怎么清理内存,于是成功搞出来了。

    这两个方法是网上拷别人的,分别用来得到可用内存和内存总数,这样我们就可用得到了已用内存数。

        private long getAvailMemory(Context context)
        {
            // 获取android当前可用内存大小
            ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            MemoryInfo mi = new MemoryInfo();
            am.getMemoryInfo(mi);
            //mi.availMem; 当前系统的可用内存
            //return Formatter.formatFileSize(context, mi.availMem);// 将获取的内存大小规格化
            return mi.availMem/(1024*1024);
        }
        private long getTotalMemory(Context context)
        {
            String str1 = "/proc/meminfo";// 系统内存信息文件
            String str2;
            String[] arrayOfString;
            long initial_memory = 0;
            try
            {
                FileReader localFileReader = new FileReader(str1);
                BufferedReader localBufferedReader = new BufferedReader(
                localFileReader, 8192);
                str2 = localBufferedReader.readLine();// 读取meminfo第一行,系统总内存大小
                arrayOfString = str2.split("\\s+");
                for (String num : arrayOfString) {
                    Log.i(str2, num + "\t");
                }
                initial_memory = Integer.valueOf(arrayOfString[1]).intValue() * 1024;// 获得系统总内存,单位是KB,乘以1024转换为Byte
                localBufferedReader.close();
            } catch (IOException e) {
            }
            //return Formatter.formatFileSize(context, initial_memory);// Byte转换为KB或者MB,内存大小规格化
            return initial_memory/(1024*1024);
        }

    在Service里面清理内存

    自己写的小方法,通过判断进程信息来判断哪些进程是无用的可用杀掉

    ActivityManager activityManger=(ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
               List<ActivityManager.RunningAppProcessInfo> list=activityManger.getRunningAppProcesses();
               if(list!=null)
               for(int i=0;i<list.size();i++)
               {
                   ActivityManager.RunningAppProcessInfo apinfo=list.get(i);
                  
                   System.out.println("pid            "+apinfo.pid);
                   System.out.println("processName              "+apinfo.processName);
                   System.out.println("importance            "+apinfo.importance);
                   String[] pkgList=apinfo.pkgList;
                  
                   if(apinfo.importance>ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE)
                   {
                      // Process.killProcess(apinfo.pid);
                       for(int j=0;j<pkgList.length;j++)
                       {
                           //2.2以上是过时的,请用killBackgroundProcesses代替
                           activityManger.restartPackage(pkgList[j]);
                       }
                   }

               }

    解析如下:

    RunningAppProcessInfo 得到正在运行的进程信息

    pkgList:得到该进程下运行的包名

    importance:该进程的重要程度

    importance分为几个级别,数值越低就越重要。数值对应的重要性请看api,我判断是大于ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE的都杀掉,一般数值大于ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE的进程都长时间没用或者空进程了。

    最后通过for循环把包名对应进程杀掉:

    2.2版本以下的用activityManger.restartPackage(pkgList[j]);   对应权限<uses-permission android:name="android.permission.RESTART_PACKAGES" />

    2.2以上的用killBackgroundProcesses(包名);    对应权限<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />

    之前我以为可用android.os.Process.killProcess(pid);来杀掉其他进程,后来发觉不行

    网上找到的解析是

    对于这个方法,需要详细解释一下。在SDK的文档中,解释如下:

    Kill the process with the given PID. Note that, though this API allows us to request to kill any process based on its PID, the kernel will still impose standard restrictions on which PIDs you are actually able to kill. Typically this means only the process running the caller's packages/application and any additional processes created by that app; packages sharing a common UID will also be able to kill each other's processes.

    英语不好,不能准确翻译,所以希望大家自己理解,免得对大家造成误解。我个人对这句话的解释就是,这个方法使用是有条件的:

    a、将被杀掉的进程 和 当前进程 处于同一个包或者应用程序中;

    b、将被杀掉的进程 是由当前应用程序所创建的附加进程;

    c、将被杀掉的进程 和 当前进程 共享了普通用户的UID。(这里的普通用户,是相对于Root权限的用户来说的)


    android Debuger 出现:"Waiting for Debugger - Application XXX is waiting for the debugger to Attach"


    在eclipse中进行调试时经常出现下面这样的提示
    Application XXX  is waiting for the debugger to attach

    但是一般情况下,过了一会之后会进入调试状态,但有时进行调试的时候模拟器上九一直停留在上面这个提示对话框,一直不能进入调试状态。。。加打印调试太麻烦而且效率太低了。

     


    解决办法如下:
     
    1、在按照网上说的在dos命令行中进行
    adb kill-server
    adb start-server
    两个命令操作之后偶尔会有效(进入调试状态)


    2、同时打开了两个eclipse进行调试,关掉一个eclipse之后便正常了
    个人认为这是一个eclipse的bug,即不能同时打开多个eclipse进行调试
    这时模拟器可能不能正确辨别是哪个eclipse正在进行debug
    从而会一直停留在“等待调试器连接”的提示上
    但是不爽的一点是eclipse不能同时打开多个进行调试,想做手机之间的通信还真不方便debug


    3、关掉eclipse重新启动试一下

     

    4、关闭电脑或手机重新启动试一下


    Android上dip、dp、px、sp等单位说明

    Androidlayout文件中有时候可能会指定具体的单位,比如有时候为pxdip或者sp等。他们的区别如下:

    1. px (pixels)像素:这个大家用得比较多,一般我们HVGA代表320x480像素。

    2. dipdp (device independent pixels)设备独立像素:这个和设备硬件有关,一般我们为了支持WVGAHVGAQVGA cwj推荐使用这个,不依赖像素。android上开发的程序将会在不同分辨率的手机上运行。为了让程序外观不至于相差太大,所以引入了dip的概念。比如定义一个矩形10 x 10dip.在分辨率为160dpi的屏上,比如G1,正好是10 x 10像素。而在240 dpi的屏,则是15 x 15像素.换算公式为pixs = dips * (density/160). density就是屏的分辨率

    3. sp (scaled pixels — best for text size)放大像素:主要处理字体的大小。

    下面的不经常用到:

    4. in (inches)英寸

    5. mm (millimeters)毫米

    6. pt (points)android:numColumns="auto_fit"GridView的列数设置为自动android:columnWidth="90dp",每列的宽度,也就是Item的宽度android:stretchMode="columnWidth",缩放与列宽大小同步android:verticalSpacing="10dp",两行之间的边距,如:行一(NO.0~NO.2)与行二(NO.3~NO.5)间距为10dp android:horizontalSpacing="10dp",两列之间的边距。

    dp与px转换的方法

    public static int dip2px(Context context, float dipValue){

      final float scale
    = context.getResources().getDisplayMetrics().density;

      return (
    int)(dipValue * scale +0.5f);

      }

      
    public static int px2dip(Context context, float pxValue){

      final float scale
    = context.getResource().getDisplayMetrics().density;

      return (
    int)(pxValue / scale +0.5f);

      }

    Android上dip、dp、px、sp等单位说明

    [ dip: device independent pixels(设备独立像素).

    不同设备有不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA、HVGA和QVGA 推荐使用这个,不依赖像素。

    px: pixels(像素). 不同设备显示效果相同,一般我们HVGA代表320x480像素,这个用的比较多。  

    pt: point,是一个标准的长度单位,1pt=1/72英寸,用于印刷业,非常简单易用;

    sp: scaled pixels(放大像素). 主要用于字体显示best for textsize。  

    =========================  

    关于换算(以 sp 和 pt 为例)   

    查看 TextView 等类的源码,可知:   

    case COMPLEX_UNIT_PX:   

    return value;   

    case COMPLEX_UNIT_SP:   

    return value * metrics.scaledDensity;   

    case COMPLEX_UNIT_PT:   

    return value * metrics.xdpi * (1.0f/72);  

    --------------------------   

    scaledDensity = DENSITY_DEVICE / (float) DENSITY_DEFAULT;

    xdpi = DENSITY_DEVICE;  

    --------------------------  

    DENSITY_DEFAULT = DENSITY_MEDIUM = 160;   

    ============================================   

    所以: 假设 pt 和 sp 取相同的值 1,则可设 1pt 和 1sp 之间系数为 x,   

    1 * DENSITY_DEVICE / 72 = x * 1 * DENSITY_DEVICE / 160 =&gt;   

    x = 160 / 72 = 2.2222   

    也就是说在 Android 中, 1pt 大概等于 2.22sp   

    =================================================================== 

     什么是Dip和Sp  

     过去,程序员通常以像素为单位设计计算机用户界面。例如,定义一个宽度为300像素的表 

    单字段,列之间的间距为5个像素,图标大小为16×16像素 等。这样处理的问题在于,如 

    果在一个每英寸点数(dpi)更高的新显示器上运行该程序,则用户界面会显得很小。在有 

    些情况下,用户界面可能会小到难以看清 内容。    

    与分辨率无关的度量单位可以解决这一问题。Android支持下列所有单位。   

    px(像素):屏幕上的点。   

    in(英寸):长度单位。   

    mm(毫米):长度单位。   

    pt(磅):1/72英寸。   

    dp(与密度无关的像素):一种基于屏幕密度的抽象单位。在每英寸160点的显示器上,1dp= 1px。   

    dip:与dp相同,多用于android/ophone示例中。   

    sp(与刻度无关的像素):与dp类似,但是可以根据用户的字体大小首选项进行缩放。   

    为了使用户界面能够在现在和将来的显示器类型上正常显示,建议大家始终使用sp作为文 字大小的单位,将dip作为其他元素的单位。当然,也可以考虑使用矢量图形,而不是用位图

    android中不同手机分辨率适配问题 2011-06-22 12:59:02

    版权声明:原创作品,谢绝转载!否则将追究法律责任。

        在项目开发的过程中,同一个布局对应不同的手机会显示出不同的效果。导致这个现象产生的原因是不同手机的分辨率不同。在android sdk提供的帮助文档中,我们可以看到各种手机的分辨率和对应的屏大小。QVGA (240x320),WQVGA400(240x400),WQVGA432 (240x432),HVGA (320x480),WVGA800 (480x800),WVGA854 (480x854)。

        目前android手机的分辨率大致就是帮助文档中描述的几种,我们可以用两种方式进行不同手机的适配。一种是在java代码中,另外一种是在xml文件中。具体使用哪种方式更有效更合适,要看具体的情况而定。

       在以前的项目中,我之前做过关于历史聊天记录,每页显示条数的匹配。不同的手机,每页可以显示历史记录的条数是不同的。我采用的是在java代码中做匹配。不同分辨率的手机,他们都有固定的屏高。例如,480x800,屏高是800,240x320,屏高是320。根据屏高为判定条件,为每一页显示历史记录的条数做一个限制。我个人觉得,在java代码中做手机匹配,要看匹配的布局中,控件是否太多,不太多,可以在java代码中根据不同的情况修改,否则,java代码将会显得很冗长,修改起来也很麻烦。

        在xml进行手机匹配,主要是针对布局中控件太多,不方便在java代码中修改的情况。在xml中解决不匹配问题很简单,对于不同手机的分辨率,建立对应的layout文件即可。例如:480x800,之间建立layout-800x400,240x320,建立layout-320x240。特别注意:大的写在前面,例如800,320,小的写在后面,例如480,240。建立了相应的layout后,还要在不同的手机上调整布局中的控件大小和位置。

        在本次项目中,我负责不同手机视图的匹配问题,我选择的是xml匹配方式,结果发现按上面的方式做了之后,对应分辨率的手机的显示没有任何的效果,后来,我查看帮助文档后,发现必须要在androidmainfest中进行如下代码的配置:

    <supports-screens
            android:smallScreens="true"
            android:normalScreens="true"
            android:largeScreens="true"
            android:xlargeScreens="true"
            android:anyDensity="true" />
    如果没有这几行代码,不管你怎么调整layout中的控件,对应分辨率的手机是没有任何效果的。注意:由于android版本的不同,有些版本不支持xlargeScreens,可以直接将android:xlargeScreens="true"去掉。

       

     

    本文出自 “花样年华” 博客


    展开全文
  • Android学习笔记Android基础知识点(不断更新中)

    万次阅读 多人点赞 2020-08-16 23:02:49
    1、Android系统的四大组件分别是:活动(Activity)、服务(Service)、广播接收器(Broadcast Receiver)、内容提供器(Content Provider)。 2、定义一个应用程序名的字符串,有以下两种方式来引用它:
  • Android学习笔记(二)

    2019-02-26 16:14:56
    文章目录十一.RecycleViewRecycleView实现水平方向滚动RecycleView实现网格视图RecycleView实现瀑布流RecycleView根据不同的ViewHolder,显示不一样十二.WebView十三.弹出组件Toast十四. 弹出对话框十五....
  •  系统会对Button中的所有英文字母自动进行大写转换,可以通过设置android: textAllCaps="false"属性来禁用。  Android控件的使用基本都很相似:定义id、指定控件宽高、加入控件特有属性。  EditText 特有属性: ...
  • Android开发笔记(序)写在前面的目录

    万次阅读 多人点赞 2019-02-01 15:19:32
    知识点分类 一方面写写自己走过的弯路掉进去的坑,避免以后再犯;另一方面希望通过分享自己的经验教训,与网友互相切磋,...还有就是有的知识点是java的,只是Android开发也会经常遇上,所以蛮记下来。个人的经验...
  • 我的Android开发相关文章

    万次阅读 多人点赞 2015-12-30 15:28:58
    Pro Android学习笔记: Pro Android学习笔记(八一):服务(6):复杂数据Parcel 2014.3.27 Pro Android学习笔记(八十):服务(5):访问远程服务 2014.3.20 Pro Android学习笔记(七九):服务(4):远程服务...
  • 1 Android学习笔记进阶之在图片上涂鸦(能清屏) 2 Android学习笔记之详细讲解画圆角图片 3 Android学习笔记进阶20之得到图片的缩略图 4 Android学习笔记进阶19之给图片加边框 5 Android学习笔记进阶18之画图并...
  • Android开发教程笔记完全版 pdf

    千次下载 热门讨论 2020-07-30 23:30:46
    Android开发教程笔记完全版 pdf.我看了一下,自己感觉可以.
  • Google Android开发精华教程

    万次阅读 2010-04-01 21:19:00
    Android是Google于2007年11月5日宣布的基于Linux平台的开源手机操作系统的名称,该平台由操作系统、中间件、用户界面和应用软件组成,号称是首个为移动终端打造的真正开放和完整的移动软件。本文汇总整理了时下关于...
  • Android 开发工程师面试指南》

    千次阅读 2016-07-20 10:36:43
    Android 开发工程师面试指南》
  • 这片文章发布,代表着我已经把本书和看完并且笔记也发布完成了,回忆了一下我看Android群英传,只用了两个月,但是看本书却花了2016年05月04日 - 2018年07月16日,整整两年多,真是惭愧 笔记链接 Android开发艺术...
  • Android文档及学习资料整理 【至2011年7月】

    千次阅读 多人点赞 2011-07-19 21:36:59
    学习参考网站Android Developers 官方开发网站,有权威的 Dev Guide 和 ReffrenceAndroid Source 官方Android全部开源源码网站,提供下载源码至本地的步骤Xda-developers Android
  • 一、解决第一次启动应用黑屏或者白屏的方法: ...android:name=".activity.SpayActivity" android:theme="@style/Theme.AppStartLoadTranslucent" android:screenOrientation="portrait" > android:
  • Android实现记事本项目完整实例,附源代码

    万次阅读 多人点赞 2014-12-03 20:24:41
    2014年12月3日14:42:40 by tops ...提供笔记列表,列表中笔记展示位标题、创建日期/修改日期 高级的可以给笔记添加照片或视频,这既可以自己拍摄也可以添加手机中已有的视频。 二、可行性分析
  • ![图片说明](https://img-ask.csdn.net/upload/201508/03/1438585727_104456.jpg)
  • http://rokonandroid.com/tutorials/41-beginner/57-getting-started本人四级未考~水平有限~权当学习笔记~仅供参考~版权的事骨头不会说~和一般博客大致相同吧~————————————————Android游戏引擎...
  • Android笔记APP的实现

    千次阅读 热门讨论 2016-06-15 11:51:36
    这两天对笔记软件进行了迭代,利用Bmob后端,实现了用户注册于笔记同步功能,下面对实现要点进行记录。备份功能同步功能使用...Material Design记事本的实现参照这篇文章吧,我只是对它进行了封装Android 入门项目No
1 2 3 4 5 ... 20
收藏数 104,431
精华内容 41,772
关键字:

android笔记