1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > Android移动应用开发

Android移动应用开发

时间:2018-12-18 20:02:34

相关推荐

Android移动应用开发

Android移动应用开发

1、认识Android2、Android界面开发方法2.1 布局控件2.2 Android常用公有属性2.3 线性布局 LinearLayout2.4 values下xml 技巧2.5 button的使用2.6 shape图形 selector2.7 相对布局ReLativeLayout的使用2.8 Spinner控件的使用2.9 Dialog对话框对的使用 3、界面跳转的实现3.1 认识Intent3.2 Activity间的数据传递3.3 Activity生命周期 4、用户信息的存储4.1 简单存储SharedPreferences4.2 文件存储 5、ListView的应用5.1 使用Adapter设置数据及布局5.2 简单适配器SimpleAdapter5.3 自定义适配器5.4 ViewHolder用法 6、单选及复选按钮6.1 复选按钮(CheckBox)6.2 单选按钮(RadioButton) 7、Fragment碎片7.1 认识Fragment7.2 添加Fragment7.3 Fragment的生命周期 8、SQLite数据库8.1 认识SQLite数据库8.2 SQLite数据库的创建8.3 SQLite数据库的升级8.4 SQLite数据库的查看8.5 SQLite数据库的基本操作

1、认识Android

1、Android的体系架构

应用程序、应用程序框架、核心类库、Linux内核

2、Dalvik虚拟机

3、ART虚拟机

2、Android界面开发方法

2.1 布局控件

1、Android界面分为布局控件

2、布局类LinearLayout继承自ViewGroup

控件类TextView继承自View(所有UI类的父类)

3、小结

带+在r文件中自动生成一个常量代替该文件

android:id=“@+id/button”

2.2 Android常用公有属性

1、layout_width、layout_height设置控件宽高

wrap_content包裹内部控件

match_parent填充父容器

2、layout_margin控件的外边距

3、padding控件的内边距

4、设置控件相对位置

layout_gravity控件相对于父控件的位置

gravity控件内容相对于控件的位置

靠左、靠右、顶部、底部:left、right、top、bottom

居中:center

水平居中:center_horizontal

垂直居中:center_vertical

2.3 线性布局 LinearLayout

1、排列规则:水平排列垂直排列

注意:默认是水平,控件不会自动换行,超出布局的不显示

2、特有属性orientation 设置方向

水平:horizontal 从左到右

垂直:vertical 从上到下

3、layout_weight

4、background和backgroundIint

background:除了纯色背景还可以加图片

backgroundIint:适用于api level 21 更高的版本

5、setTextColor修改颜色的三种方式

(Color.RED)

(Color.rgb(0,0,255))

(Color.parseColor(“#66CCFF”))

2.4 values下xml 技巧

1、colors.xml定义颜色

<resources><color name="color">#3F51B5</color></resources>android:textColor="@color/color"

2、string.xml定义字符串

<resources><string name="hello">hello</string></resources>android:text="@string/hello"

2.5 button的使用

1、ImageButton

<ImageButtonandroid:id="@+id/button16"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:background="@drawable/selector_button"android:scaleType="fitXY"android:src="@mipmap/sqrt" />

src:前景

background:背景

fitXY:图片适应控件大小

2、单个Button的事件处理

button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {textView.setTextColor(Color.parseColor("red"));}});

3、多个Button的事件处理

总体思路:使用switch方法

在Activity中实现事件监听接口

public class MainActivity extends AppCompatActivity implements View.OnClickListener{//此处省略部分代码@Overridepublic void onClick(View view) {switch (view.getId()){case R.id.button:textView.setTextColor(Color.parseColor("red"));break;case R.id.button2:textView.setTextColor(Color.YELLOW);break;case R.id.button3:textView.setTextColor(Color.GREEN);break;}}}

也可在Activity构造方法后,在xml布局中调用onClick

<Buttonandroid:id="@+id/button"android:text="红色"android:backgroundTint="@color/red"style="@style/buttonstyle" android:onClick="doLogin"/>

2.6 shape图形 selector

1、利用shape属性构建一个圆形

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="/apk/res/android" android:shape="rectangle"><!-- 大小--><size android:height="180dp" android:width="400dp"/><!-- 填充颜色--><solid android:color="@color/white"/><!-- 描边--><stroke android:color="@color/black" android:width="1dp" android:dashWidth="3dp" android:dashGap="1dp"/><!-- 圆角半径--><corners android:radius="10dp"/></shape>

2、selector 点击图片后显现另一个图片

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="/apk/res/android"><!-- 不设置状态的这一行,一定要写在最后面,否则不起作用--><item android:state_pressed="true" android:drawable="@drawable/button_pressed_orig"/><item android:drawable="@drawable/button_normal_orig"/></selector>

2.7 相对布局ReLativeLayout的使用

1、兄弟控件

2、父控件

2.8 Spinner控件的使用

1、spinner列表框模式

android:spinnerMode

dialog:弹出对话框

dropdown:下拉框

android:entries 设置列表项,值为数组资源

android:popupBackground 设置下拉项的背景

2、spinner列表框实现方式一

<Spinnerandroid:id="@+id/spanner_dropdown"android:layout_width="wrap_content"android:layout_height="wrap_content"android:entries="@array/dropdown"android:spinnerMode="dropdown"android:popupBackground="@color/teal_700"></Spinner>

values/arrs.xml

<resources><string-array name="dropdown"><item>软件二班</item><item>软件一班</item><item>软件三班</item><item>软件四班</item></string-array></resources>

2、spinner列表框实现方式二

<Spinnerandroid:id="@+id/spinner_dialog"android:layout_width="wrap_content"android:layout_height="wrap_content"android:spinnerMode="dialog"></Spinner>

//1.获取列表控件spinner=findViewById(R.id.spinner_dialog);//2.准备数据String arr[]=new String[]{"北京","上海","潍坊","西双版纳"};//3.创建adapter适配器对象上下文、列表项数据的布局数据//this 当前类对象对象,监听器类,监听器不能充当上下文ArrayAdapter arrayAdapter=new ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_1,arr);//4.设置adapterspinner.setAdapter(arrayAdapter);

2.9 Dialog对话框对的使用

1、简单对话框

(1)调用AlertDialog 的静态内部类 Builder创建AlertDialog. Builder对象。

(2)调用AlertDialog.Builder的 setTitle()和setIcon( )方法设置对话框的标题名称和图标。

(3)调用AlertDialog.Builder 的setMessage( )、setSingleChoiceItems()等方法设置对话框的提示信息、单选选项等显示内容。

(4)调用AlertDialog.Builder的setPositiveButton()和 setNegativeButton()方法设置对话框的“确认”和“取消”按钮。

(5)调用AlertDialog. Builder 的 create()方法创建AlertDialog 对象。

(6)调用AlertDialog 对象的show()方法显示对话框。

(7)调用AlertDialog对象的dismiss()方法取消对话框。

2、单选对话框

private void genderDialog() {String[] genders=new String[]{"男","女"};AlertDialog.Builder builder=new AlertDialog.Builder(this);builder.setTitle("选择性别");builder.setSingleChoiceItems(genders, 0, new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialogInterface, int i) {gender1.setText(genders[i]);dialogInterface.dismiss();}});AlertDialog dialog=builder.create();dialog.show();}

3、多选对话框

AlertDialog.Builder b = new AlertDialog.Builder(this);final String items[]=new String[]{"音乐", "画画", "游泳", "电影", "游戏", "运动"};boolean[] checks=new boolean[]{false, false, false, false, false, false};b.setTitle("选择你喜欢的项目:");/*b.setMultiChoiceItems第一个参数为复选按钮组,第二个为是否默认选中,对应复选按钮组,true为默认选中,第三个为监听事件*/b.setMultiChoiceItems(items, checks, new DialogInterface.OnMultiChoiceClickListener(){@Overridepublic void onClick(DialogInterface dialog, int which, boolean isChecked) {Toast.makeText(MainActivity.this, "你选择了"+items[which], Toast.LENGTH_SHORT).show();}});b.setPositiveButton("确定", null);b.show();//显示对话框

4、日期对话框

private void birthdayDialog() {Calendar c=Calendar.getInstance();int year1=c.get(Calendar.YEAR);int month1=c.get(Calendar.MONTH);int day1=c.get(Calendar.DAY_OF_MONTH);DatePickerDialog dialog=new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() {@Overridepublic void onDateSet(DatePicker datePicker, int i, int i1, int i2) {birthday1.setText(i+"年"+(i1+1)+"月"+i2+"日");}},year1,month1,day1);dialog.show();}

5、自定义对话框

private void usernameDialog() {View v=View.inflate(this,R.layout.dialog_username,null);AlertDialog.Builder builder=new AlertDialog.Builder(this);builder.setTitle("修改昵称");builder.setView(v);builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialogInterface, int i) {EditText ed1_up=v.findViewById(R.id.ed1);String name=ed1_up.getText().toString().trim();username1.setText(name);}});builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialogInterface, int i) {}});AlertDialog dialog=builder.create();dialog.show();}

3、界面跳转的实现

3.1 认识Intent

1、显式Intent

Intent intent=new Intent(MainActivity.this,SecondActivity.class);startActivity(intent);

2、隐式Intent

AndroidManifest.xml

<activityandroid:name=".MainActivity"android:exported="true"><intent-filter>//过滤器<action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><activityandroid:name=".SecondActivity"android:exported="false"><intent-filter><action android:name="com.example.appjump.SecondActivity"/><category android:name="android.intent.category.DEFAULT"/></intent-filter></activity>

MainActivity.java

Intent intent=new Intent("com.example.appjump.SecondActivity");startActivity(intent);

3.2 Activity间的数据传递

1、向下一个Activity传递数据

(1)、单个存取

Intent intent=new Intent("com.example.appjump.SecondActivity");String t=t1.getText().toString().trim();intent.putExtra("text",t);

Intent intent=getIntent();String text=intent.getStringExtra("text");

(2)、打包存取

Intent intent=new Intent("com.example.appjump.SecondActivity");Bundle bundle=new Bundle();bundle.putString("name",uname);bundle.putString("password",pas);intent.putExtra(bundle);

Intent intent=getIntent();Bundle bundle=intent.getExtras();String name=bundle.getString("name");String password=bundle.getString("password");

2、返回数据给上一个Activity

@Overridepublic void onClick(View view) {switch (view.getId()){case R.id.button1:Intent intent=new Intent("com.example.appjump.SecondActivity");String t=t1.getText().toString().trim();intent.putExtra("text",t);startActivityForResult(intent,2);break;}}

@Overridepublic void onClick(View view) {Intent intent1=new Intent(SecondActivity.this,MainActivity.class);String t2=e1.getText().toString().trim();intent1.putExtra("text2",t2);setResult(RESULT_OK,intent1);}

@Overrideprotected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {super.onActivityResult(requestCode, resultCode, data);if(requestCode==2){if(resultCode==RESULT_OK){String text2=data.getStringExtra("text2");t1.setText(text2);}}}

3.3 Activity生命周期

@Overridepublic void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {super.onCreate(savedInstanceState, persistentState);Log.e("生命周期","onCreate");}@Overrideprotected void onStart() {super.onStart();Log.e("生命周期","onStart");}@Overrideprotected void onResume() {super.onResume();Log.e("生命周期","onResume");}@Overrideprotected void onPause() {super.onPause();Log.e("生命周期","onPause");}@Overrideprotected void onStop() {super.onStop();Log.e("生命周期","onStop");}@Overrideprotected void onRestart() {super.onRestart();Log.e("生命周期","onRestart");}@Overrideprotected void onDestroy() {super.onDestroy();Log.e("生命周期","onDestroy");}@Overrideprotected void onSaveInstanceState(@NonNull Bundle outState) {super.onSaveInstanceState(outState);Log.e("生命周期","onSavaInstanceState");}

4、用户信息的存储

4.1 简单存储SharedPreferences

1、存储形式

键值对

2、存储位置

/data/data/<包名>/shared-prefs

3、存数据

SharedPreferences spf=getSharedPreferences("data",MODE_PRIVATE);SharedPreferences.Editor editor=spf.edit();editor.putString("username","nolan");editor.putString("password","123456");mit();

4、取数据

SharedPreferences spf1=getSharedPreferences("data",MODE_PRIVATE);String name=spf1.getString("username","admin");//第二个参数为默认值

4.2 文件存储

1、内部存储

(1)存储位置

/data/data/<包名>/files

(2)存文件

private void saveData() {//String fileName="mydb.txt"; //文件名称//String strNr="HelloWorld,我被写出来啦!";//要保存的数据String a=ed1.getText().toString();FileOutputStream fos=null;try {fos=openFileOutput(fileName,MODE_PRIVATE);fos.write(a.getBytes());//将数据写入文件中去Toast.makeText(this,"存入数据成功",Toast.LENGTH_LONG).show();} catch (Exception e) {e.printStackTrace();}finally {try {if(fos!=null) {fos.close();}}catch (Exception ex){ex.printStackTrace();}}}

(3)取文件

private void readData() {String strNr="";FileInputStream fis=null;try {fis=openFileInput(fileName);//获取输入流对象byte[] buffer=new byte[fis.available()]; //创建数据的缓冲fis.read(buffer);strNr=new String(buffer);//将内容转换成字符串text.setText(strNr);Toast.makeText(this,"读取数据成功",Toast.LENGTH_LONG).show();}catch (Exception ex){ex.printStackTrace();} finally {try {if(fis!=null){fis.close();}}catch (Exception ex){ex.printStackTrace();}}}

2、外部存储

(1)存储位置

Environment.getExternalStorageDirectory().getPath():该方法返回外部存储根路径,返回值为"String"

/storage/emulated/0

(2)创建文件

public static File getFile(String filePath) {//通过文件路径创建文件对象File file = new File(filePath);//判断父文件夹是否存在 如果不存在则创建文件夹if (!file.getParentFile().exists()) {file.getParentFile().mkdirs();}//判断文件是否存在 如果不存在则创建文件if (!file.exists()) {try {file.createNewFile();} catch (Exception e) {Log.e("创建失败", e.getMessage());}}return file;}

(3)申请权限

1、Androud6.0以下的版本

在AndroidManifest.xml中对所需权限进行声明

manifest节点和application节点之间

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

2、Androud6.0~10.0的版本

步骤一:在Activity的onCreate()方法中,添加动态权限申请

if(ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this,Manifest.permission.READ_EXTERNAL_STORAGE)!=PackageManager.PERMISSION_GRANTED){Log.e("权限问题","有权限么");ActivityCompat.requestPermissions(this,new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE},1);}else {saveData(filePath, a);}

步骤二:添加回调方法onRequestPermissionsResult()

@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if(requestCode==1){//判断请求码for(int i=0;i<permissions.length;i++){//循环判断权限授予结果if(grantResults[i]==PackageManager.PERMISSION_GRANTED){Toast.makeText(this,"权限"+permissions[i]+"申请成功",Toast.LENGTH_LONG).show();}else {Toast.makeText(this,"权限"+permissions[i]+"申请失败",Toast.LENGTH_LONG).show();}}}}

3、Androud10.0以上的版本

在AndroidManifest.xml的application节点中,加入以下属性设置

android:requestLegacyExternalStorage="true"

(4)存文件

private void saveData(String filePath,String content) {//调用getFile()方法创建文件并返回File file=getFile(filePath);FileWriter fw=null;BufferedWriter bw=null;try {//创建缓冲流对象实现数据的写入fw=new FileWriter(file,false);bw=new BufferedWriter(fw);bw.write(content);Toast.makeText(this,"数据存入成功",Toast.LENGTH_LONG).show();} catch (IOException e) {Log.e("写文件出错",e.getMessage());}finally {try {//先关包装流,再关节点流if(bw!=null)bw.close();if(fw!=null)fw.close();}catch (IOException e){e.printStackTrace();}}}

(5)取文件

private String readData(String filePath) {File file=new File(filePath);String s=null;StringBuilder stringBuilder=new StringBuilder();FileReader fr=null;BufferedReader reader=null;int count=0;try{//创建缓冲流对象fr=new FileReader(file);reader=new BufferedReader(fr);//循环按行读取数据while ((s=reader.readLine())!=null){stringBuilder.append(s);}Toast.makeText(this,"数据读取成功",Toast.LENGTH_LONG).show();}catch (Exception e){Log.e("读取文件出错",e.getMessage());}finally {try{if(reader!=null)reader.close();if(fr!=null)fr.close();}catch (IOException e){e.printStackTrace();}}return stringBuilder.toString();}

5、ListView的应用

5.1 使用Adapter设置数据及布局

1、在布局文件中加入ListView控件

2、写好列表项的布局文件

3、准备将要在列表项中显示的数据,可以为数组或集合

4、创建Adapter对象,设置选中项的显示布局和数据

5、将Adapter对象设置给ListView对象

5.2 简单适配器SimpleAdapter

将数据转给布局中的控件

//List继承自Map集合,data:List对象,List中的对象:Map集合的对象,Map对象:键:String 值:不知道是什么类型//一个Map对象代表一个列表项,有几个列表项就有几个Map//准备数据String[] names=new String[]{"太阳","水星","金星","地球","火星","木星","土星","天王星","海王星"};int[] images=new int[]{R.mipmap.ty,R.mipmap.sx,R.mipmap.jx,R.mipmap.dq,R.mipmap.hx,R.mipmap.mx,R.mipmap.tx,R.mipmap.twx,R.mipmap.hwx};//创建一个List对象ArrayList list=new ArrayList();//一个列表项的数据组成一个Map对象for(int i=0;i< names.length;i++){HashMap map=new HashMap();map.put("image",images[i]);map.put("name",names[i]);list.add(map);}//准备适配器 //第1个参数:上下文对象,第2个参数:数据集合 List集合,其中元素是Map对象,第3个参数:列表项布局//第4个参数:Map中键的数组,第5个参数:是布局中控件的id,键和id的数组要一一对应SimpleAdapter adapter=new SimpleAdapter(this,list,R.layout.item_list,new String[]{"image","name"},new int[]{R.id.iv_icon,R.id.tv_name});//列表项item点击事件处理l1.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Override//第1个参数:点击的Adapter对象,第2个参数:点击的item,第3个参数:位置 第i个item,第4个参数:item在listview第几行 一般3和4是一样的public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {Toast.makeText(ListActivity.this, "您选择的是"+names[i], Toast.LENGTH_SHORT).show();}});

5.3 自定义适配器

ArrayAdapter适用于列表项中包含一个TextView

SimpleAdapter有固定的数据组织形式

ArrayAdapterSimpleAdapter继承BaseAdapter抽象类

1、MyAdapter.java自定义适配器将存储的数据转给控件

public class MyAdapter extends BaseAdapter {private List<Planet> data;//数据集合private int layoutId;//列表项布局idprivate Context context;//上下文对象public MyAdapter(Context context,List<Planet> data,int layoutId){this.context=context;this.data=data;this.layoutId=layoutId;}//获取列表项个数@Overridepublic int getCount() {return data.size();}//获取i位置上的列表项对象@Overridepublic Object getItem(int i) {return data.get(i);}//获取i位置上的列表项的id,当前元素的位置@Overridepublic long getItemId(int i) {return i;}//将i位置上的数据放到列表项布局中@Overridepublic View getView(int i, View view, ViewGroup viewGroup) {//数据位置 List集合data中,取出i位置的数据Planet planet=data.get(i);String name=planet.getName();int image=planet.getImage();//通过Inflater对象的inflate方法将布局转成一个view对象,再通过view对象findViewById找控件//获取LayoutInflater实例,从一个Context中,获得一个布局管理器LayoutInflater inflater=LayoutInflater.from(context);//将xml布局转换为view对象,找到xml布局View v=inflater.inflate(layoutId,null);ImageView imageView=v.findViewById(R.id.iv_icon);TextView textView=v.findViewById(R.id.tv_name);//将数据放到相应的控件上imageView.setImageResource(image);textView.setText(name);return v;}}

2、ListActivity.java调用适配器完成存储

public class ListActivity extends AppCompatActivity {private ListView l1;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_list);l1=findViewById(R.id.l1);//创建一个List对象ArrayList list=new ArrayList();list.add(new Planet("太阳",R.mipmap.ty));list.add(new Planet("水星",R.mipmap.sx));list.add(new Planet("金星",R.mipmap.jx));list.add(new Planet("地球",R.mipmap.dq));list.add(new Planet("火星",R.mipmap.hx));list.add(new Planet("木星",R.mipmap.mx));list.add(new Planet("土星",R.mipmap.tx));list.add(new Planet("天王星",R.mipmap.twx));list.add(new Planet("海王星",R.mipmap.hwx));//自定义适配器MyAdapter adapter=new MyAdapter(this,list,R.layout.item_list);l1.setAdapter(adapter);}}

5.4 ViewHolder用法

ViewHolder通常出现在适配器里,为的是ListView滚动的时候快速设置值,而不必每次都重新创建很多对象,从而提升复用性,要按需填充并重新使用view来减少对象的创建。优化ListView的加载速度就要让convertView匹配列表类型,并最大程度上的重新使用convertView。

定义一个ViewHolder,将convetView的tag设置为ViewHolder,不为空时重新使用即可

@Overridepublic View getView(int i, View view, ViewGroup viewGroup) {ViewHolder holder=null;if(view==null){//创建ViewHolder对象 承载的是每一个列表项的视图holder=new ViewHolder();//将列表项布局转为View对象LayoutInflater inflater=LayoutInflater.from(context);view=inflater.inflate(R.layout.item_jf,null);//获取控件holder.t1=view.findViewById(R.id.tv_name);holder.t2=view.findViewById(R.id.tv_describe);holder.b1=view.findViewById(R.id.tv_button);//Tag从本质上来讲是就是相关联的view的额外的信息,经常用来存储一些view的数据view.setTag(holder);}else{//放着控件引用的ViewHolder对象,可以去复用holder= (ViewHolder) view.getTag();}//取数据Description description=data.get(i);holder.t1.setText(description.getItname());holder.t2.setText(description.getZtname());return view;}//创建内部类public final class ViewHolder{public TextView t1;public TextView t2;public Button b1;}

6、单选及复选按钮

6.1 复选按钮(CheckBox)

1、继承关系及使用方法

CheckBox继承CompoundButton

android:checked设置按钮的勾选状态 true/false

CompoundButton分为两个部分,左侧是勾选图标,右侧是选项文字

若将andriod:button的值设为“@null”,则可以去掉左侧的勾选图标

若不设置android:text的值,则仅有左侧的勾选图标,没有右侧的选项文字

2、activity_main.xml

采用线性布局水平排列,有几个按钮选项就设几个TextView

<LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="你喜欢什么运动?"android:textColor="@color/black"android:textSize="20dp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/t1"android:textSize="15dp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/t2"android:textSize="15dp"/></LinearLayout><CheckBoxandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="跑步"android:id="@+id/cb1"/><CheckBoxandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="游泳"android:id="@+id/cb2"/>

3、MainActivity.java

实现CompoundButton.OnCheckedChangeListener 接口,重写onCheckedChanged()方法

public class MainActivity extends AppCompatActivity implements CompoundButton.OnCheckedChangeListener {private TextView t1,t2;private CheckBox cb1,cb2;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);t1=findViewById(R.id.t1);t2=findViewById(R.id.t2);cb1=findViewById(R.id.cb1);cb2=findViewById(R.id.cb2);cb1.setOnCheckedChangeListener(this);cb2.setOnCheckedChangeListener(this);}@Override//第一个参数是按钮对象,第二个参数是当前状态public void onCheckedChanged(CompoundButton compoundButton, boolean b) {switch (compoundButton.getId()){case R.id.cb1:if(b){t1.setText("A");}else {t1.setText("");}break;case R.id.cb2:if(b){t2.setText("B");}else {t2.setText("");}break;}}}

6.2 单选按钮(RadioButton)

1、继承关系及使用方法

RadioButton继承CompoundButton

RadioButton通常与单选组合框RadioGroup配合使用,以实现单选按钮间的互斥功能,RadioGroup中可以包含多个RadioButton。而且RadioGroupLinearLayout的子类,可以通过android:orientation属性设置RadioButton的排列方式。

getCheckedRadioButtonId():获取当前选中的单选按钮ID

2、activity_main.xml

<RadioGroupandroid:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/rg"android:orientation="vertical"><RadioButtonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/rb1"android:text="肯定真ikun"/><RadioButtonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/rb2"android:text="必是小黑子"/></RadioGroup>

3、MainActivity.java

public class MainActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener{private TextView t1;private RadioGroup rg;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);rg=findViewById(R.id.rg);t1=findViewById(R.id.t1);rg.setOnCheckedChangeListener(this);}@Override//第一个参数为RadioGroup对象,第二个参数为选中单选选项IDpublic void onCheckedChanged(RadioGroup radioGroup, int i) {switch (i){case R.id.rb1:t1.setText("A");break;case R.id.rb2:t1.setText("B");break;}}}

7、Fragment碎片

7.1 认识Fragment

Fragment把屏幕划分为几个碎片,对界面进行模块化处理,是一种嵌入Activity的UI片段

一个Activity中可以包含多个Fragment,一个Fragment也可以在多个Activity中使用

7.2 添加Fragment

1、在布局文件中添加

将Fragment作为一个控件加入布局文件中

在标签中需要添加“android:name”属性,其值为Fragment的完整路径名

<fragmentandroid:id="@+id/fm2"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="2"android:name="com.example.newsdemo.BlankFragment2"/>

2、通过代码动态添加

在布局文件中加入一个布局容器FrameLayout

<FrameLayoutandroid:id="@+id/framelayout"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"/>

在Activity中调用方法

public class BlankFragment2 extends Fragment {Button button;FragmentManager manager;@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {//将布局转为view对象View view=inflater.inflate(R.layout.fragment_blank2, container, false);button=view.findViewById(R.id.b1);//获取FragmentManger对象manager=getActivity().getSupportFragmentManager(); button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {//获取FragmentTransaction对象 Fragment事务FragmentTransaction transaction=manager.beginTransaction();BlankFragment fragment=new BlankFragment();//第1个参数:要把Fragment添加到哪个控件,第2个参数:要添加的Fragment对象//add方法添加碎片不会移除已经添加的碎片。但是replace会先清除所有碎片然后才添加新的碎片transaction.add(R.id.framelayout,fragment);mit();}});return view;}}

7.3 Fragment的生命周期

由于Fragment不能独立存在,因此Fragment的生命周期直接受所在Activity 的影响。当在Activity中创建Fragment 时,Fragment 处于启动状态;当Activity暂停时,其上的所有Fragment都暂停;当Activity被销毁时,其上的所有Fragment 都被销毁。

以下5个生命周期方法是Fragment生命周期独有的方法:

onAttatch( ): Fragment 与Activity 建立关联时调用。

onCreate View( ):创建Fragment视图时调用,主要用于加载布局;在该方法返回后,会立即调用onViewCreate( )方法。

onActivityCreated( ): 在Activity 创建完毕后调用。

onDestroyView( ): Fragment关联的视图被销毁时调用。

onDetach( ): Fragment和Activity 解除关联时调用。

8、SQLite数据库

8.1 认识SQLite数据库

SQLite是一种轻量级的关系型数据库,运行速度快,占用资源少,特别适合在移动设备上使用。

SQLite数据库支持标准的SQL语法,但比一般的数据库简单,不需要安装,不需要设置用户名和密码就可以使用。

8.2 SQLite数据库的创建

要创建SQLite数据库,需要先创建一个类继承SQLiteOpenHelper类,在该类中重写onCreate( ) 和OnUpgrade( ) 方法。

1、下面我们创建一个名为“UserManager.db”数据库,并在此库中创建一张“users”表,存放用户信息

MyDataBaseHelp.ava

public class MyDataBaseHelp extends SQLiteOpenHelper {//将建表语句定义为一个字符串常量public static final String CREATE_USERS="create table users("+"id integer primary key autoincrement,"+"username text,"+"password text,"+"age integer)";private Context context;//第一个参数:上下文,第二个参数:数据库名,第三个参数:在查询数据时返回一个自定义Cursor 一般为null,第四个参数:当前数据库版本号public MyDataBaseHelp(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {super(context, name, factory, version);this.context=context;}//创建数据库@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL(CREATE_USERS);//执行建表语句Toast.makeText(context,"数据库创建完毕",Toast.LENGTH_LONG).show();}}

2、创建MyDataBaseHelper对象,调用getReadableDatabase( ) 或getWritableDatabase( ) 方法,创建数据库

MainActivity.java

public class MainActivity extends AppCompatActivity implements View.OnClickListener {private MyDataBaseHelp dataBaseHelp;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);dataBaseHelp=new MyDataBaseHelp(this,"UserManager.db",null,1);dataBaseHelp.getWritableDatabase();}}

8.3 SQLite数据库的升级

在原有users表的基础上,再增加部门表department,进行数据库的更新(可以只看方法三

方法一:在onCreate( )方法,执行department建表语句

public class MyDataBaseHelp extends SQLiteOpenHelper {public static final String CREATE_USERS="create table users("+"id integer primary key autoincrement,"+"username text,"+"password text,"+"age integer)";public static final String CREATE_DEPARTMENT="create table department("+"id integer primary key autoincrement,"+"departmentname text,"+"departnamecode text)";private Context context;public MyDataBaseHelp(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {super(context, name, factory, version);this.context=context;}//创建数据库@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL(CREATE_USERS);//执行建表语句db.execSQL(CREATE_DEPARTMENT);Toast.makeText(context,"数据库创建完毕",Toast.LENGTH_LONG).show();}}

运行程序,可以发现没有弹出“数据库创建成功”的提示,没有创建department表,这是因为程序运行过,数据库就已经存在了,onCreate( )方法不会再执行,除非删除数据库,才会再次执行,显然这种方法是不合理的,所以我们可以用onUpgrade( )升级方法。

方法二:在onUpgrade( )方法中,进行数据库的更新

public class MyDataBaseHelp extends SQLiteOpenHelper {//省略@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {db.execSQL("drop table if exists users");db.execSQL("drop table if exists department");onCreate(db);}}

执行两条drop语句,如果两个表都存在,就删除,然后调用onCreate( )方法重新创建表,这样可以避免重新创建时因表存在而导致程序报错

执行时,在创建MyDataBaseHelper对象时传入当前数据库版本号(比旧版本号大就行

public class MainActivity extends AppCompatActivity implements View.OnClickListener {private MyDataBaseHelp dataBaseHelp;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);dataBaseHelp=new MyDataBaseHelp(this,"UserManager.db",null,2);dataBaseHelp.getWritableDatabase();}}

但是这种方法会将原数据表删除,会使存储的本地数据全部丢失,所以还是看更好的方法三吧

方法三:只要指定的数据库版本号大于当前的版本号,就会进入onUpgrade( )方法,对当前数据库版本号进行判断,在执行相应的数据库更新操作

public class MyDataBaseHelp extends SQLiteOpenHelper {//省略@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {switch (oldVersion){case 1:db.execSQL(CREATE_DEPARTMENT);}}}

通过switch判断当前版本号是1,就会只创建department表,如果有第3个版本数据库更新,就添加新的case语句,判断当前版本号为2.

注意

1、activity和dao方法中的传参也要跟着变

2、case语句后没有break,这样可以在跨版本升级时,每一次数据库的修改语句都能全部执行

8.4 SQLite数据库的查看

数据库的存储位置与SharedPreferences相同,在datda/data/包名/目录下,查看数据可以使用Android调试桥(adb),存放在SDKplatform-tools目录下,可以用cmd打开

步骤一:配置环境变量

将platform-tools目录添加到环境变量中系统变量的Path中

步骤二:在cmd中输入”adb shell“命令,进入设备控制台

步骤三:使用cd命令,转到data/data/包名/databases目录下

若出现上图中的”Permission denied“,则表示没有查看系统的权限,要通过”su root“命令,更换系统用户

步骤四:使用ls命令,查看该目录下的文件

步骤五:输入”sqlite3 数据库名“,打开数据库

输入”.table“命令,可以查看数据库中的表,通过”.schema“命令可查看建表语句,也可用sql语句进行数据库操作

步骤六:输入”.quit“退出数据库调试,回到adb,输入”exit“命令退出设备控制台

8.5 SQLite数据库的基本操作

在这里我补充一个对数据进行增、删、改、查的案例,以users表为例

1、创建MyDataBaseHelper继承SQLiteOpenHelper,创建User实体类,在activity_main.xml完成布局,此处不再赘述

2、创建UserDao类,封装增、删、改、查方法

public class UserDao {private MyDataBaseHelp dataBaseHelp;public UserDao(Context context){dataBaseHelp=new MyDataBaseHelp(context,"UserManager.db",null,2);}//添加数据public long addUser(User user){//1.获取数据库对象SQLiteDatabase db=dataBaseHelp.getWritableDatabase();ContentValues values=new ContentValues();//key:数据表的列名,value:值values.put("username",user.getUsername());values.put("password",user.getPassword());values.put("age",user.getAge());//第一个参数:表名,第二个参数:自动赋值为null的列名,第三个参数:数据//返回值:long,返回行号,如果添加不成功,返回-1long id=db.insert("users",null,values);//数据库关闭db.close();return id;}//查询数据public ArrayList queryUser(){ArrayList list=new ArrayList();SQLiteDatabase db=dataBaseHelp.getWritableDatabase();//query的参数对应于select查询sql语句中的各个部分//db.query("users",new String[]{"id","username","password","age"},"id=?",new String[]{id},null,null,null);//db.rawQuery();//接受sql语句作为参数Cursor cursor=db.query("users",null,null,null,null,null,null);//遍历cursor将数据放到list中list=convertFromCursor(cursor);return list;}private ArrayList convertFromCursor(Cursor cursor){ArrayList list=new ArrayList();//有没有返回值,是否查到结果,如果true,则有if(cursor!=null&&cursor.moveToFirst()){do{int id=cursor.getInt(cursor.getColumnIndexOrThrow("id"));String username=cursor.getString(cursor.getColumnIndexOrThrow("username"));String password=cursor.getString(cursor.getColumnIndexOrThrow("password"));int age=cursor.getInt(cursor.getColumnIndexOrThrow("age"));User user=new User(id,username,password,age);list.add(user);}while (cursor.moveToNext());//true还有数据,继续遍历}else{list=null;}return list;}//修改数据public int updateUser(User user){SQLiteDatabase db=dataBaseHelp.getWritableDatabase();ContentValues values=new ContentValues();values.put("password",user.getPassword());values.put("age",user.getAge());int i=db.update("users",values,"username=?",new String[]{user.getUsername()});db.close();return i;}//删除数据public int deleteUser(User user){SQLiteDatabase db=dataBaseHelp.getWritableDatabase();int n=db.delete("users","username=?",new String[]{user.getUsername()});db.close();return n;}}

3、在MainActivity中编写逻辑代码,实现增、删、改、查功能

public class MainActivity extends AppCompatActivity implements View.OnClickListener {private EditText et_username,et_password,et_age;private Button bt_save,bt_query,bt_update,bt_delete;private TextView tv_show;private MyDataBaseHelp dataBaseHelp;private UserDao userDao;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);dataBaseHelp=new MyDataBaseHelp(this,"UserManager.db",null,2);dataBaseHelp.getWritableDatabase();userDao=new UserDao(this);init();}public void init(){et_username = findViewById(R.id.et_username);et_password = findViewById(R.id.et_password);et_age = findViewById(R.id.et_age);bt_save = findViewById(R.id.bt_save);bt_query = findViewById(R.id.bt_query);bt_update = findViewById(R.id.bt_update);bt_delete = findViewById(R.id.bt_delete);tv_show = findViewById(R.id.tv_show);bt_save.setOnClickListener(this);bt_query.setOnClickListener(this);bt_update.setOnClickListener(this);bt_delete.setOnClickListener(this);}@Overridepublic void onClick(View view) {switch (view.getId()) {//保存数据case R.id.bt_save:String uname= et_username.getText().toString();String psw= et_password.getText().toString();int age=Integer.parseInt(et_age.getText().toString());User u=new User(uname,psw,age);long id=userDao.addUser(u);if(id!=-1){Toast.makeText(this,"保存成功",Toast.LENGTH_LONG).show();}else{Toast.makeText(this,"保存失败",Toast.LENGTH_LONG).show();}break;//查询数据case R.id.bt_query:ArrayList users= userDao.queryUser();StringBuffer stringBuffer=new StringBuffer();if(users.size()==0){tv_show.setText("无数据");}else{for(int i=0;i<users.size();i++){User u1= (User) users.get(i);stringBuffer.append("ID: "+u1.getId() +" 用户名: "+u1.getUsername() +" 密码: "+u1.getPassword() +" 年龄: "+u1.getAge() +"\n");}tv_show.setText(stringBuffer);}break;//修改数据case R.id.bt_update:String uname1=et_username.getText().toString();String psw1=et_password.getText().toString();int age1=Integer.parseInt(et_age.getText().toString());User u1=new User(uname1,psw1,age1);int i=userDao.updateUser(u1);if(i!=0){Toast.makeText(this,"修改成功",Toast.LENGTH_LONG).show();}else{Toast.makeText(this,"修改失败",Toast.LENGTH_LONG).show();}break;//删除数据case R.id.bt_delete:String uname2=et_username.getText().toString();User u2=new User(uname2);int n= userDao.deleteUser(u2);if(n!=0){Toast.makeText(this,"删除成功",Toast.LENGTH_LONG).show();}else{Toast.makeText(this,"删除失败",Toast.LENGTH_LONG).show();}break;}}}

注意:除了以上方法,还可以用SQL语句对数据库进行增、删、改、查操作

//增db.execSQL("insert into users(username,password) values(?,?)",new Object[]{name,password});//删db.execSQL("delete from users where id=1");//改db.execSQL("update users set password=? where username=?",new Object[]{password,username});//查Cursor cursor=db.rawQuery("users",new String[]{"id","username","password","age"},"id=?",new String[]{id},null,null,null);

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。