上手开发Android需要掌握什么呐
一、Intent传值
在这里,我们从MainActivity中向EditTextActivity中传值,并取回用户在文本框中输入的内容。
//MainActivity中的方法
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//MainActivity中向EditTextActivity中传值
Intent intent = new Intent(MainActivity.this, EditTextActivity.class);
intent.putExtra("name", "value");
//启动活动,获取结果
startActivityForResult(intent, 0);
}
});
//第二个方法
//接收startActivityForResult的结果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode,resultCode,data)
String edit = data.getStringExtra("input")
}
//在EditTextActivity中接收
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_HOME) {
return true;
} else if (keyCode == KeyEvent.KEYCODE_BACK) {
Intent intent = new Intent();
autoSetMessage(intent);
//按下返回键,将页面的文本获取,并返回
// intent.putExtra("内容", editText.getText().toString());
setResult(RESULT_OK, intent);
finish(); //关闭活动
return true;
}
return super.onKeyDown(keyCode, event);
}
二、数据库—Database类和CRUD
首先用代码介绍一下Database的类
public class NoteDatabase extends SQLiteOpenHelper {
//设置常量,通过设置属性名,方便后期项目管理,对其识别
public static final String TABLE_NAME = "notes";
//content属性表示内容
public static final String CONTENT = "content";
//id属性用于定位数据,可在数据库中设置AUTOINCREMENT实现自增长
public static final String ID = "_id";
public static final String TIME = "time";
public static final String MODE = "mode";
public NoteDatabase(Context context) {
super(context, "notes", null, 1);
}
//创建数据库
//实际上就是写SQL,创建表
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME + "(" + ID
+ " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ CONTENT + " TEXT NOT NULL, "
+ TIME + " TEXT NOT NULL, "
+ MODE + " INTEGER DEFAULT 1)");
}
}
CRUD类
public class CRUD {
SQLiteOpenHelper dbHandler; //数据库处理器
SQLiteDatabase db; //定义数据库
//取出数据库的数据
private static final String[] columns = {
NoteDatabase.ID,
NoteDatabase.CONTENT,
NoteDatabase.TIME,
NoteDatabase.MODE
};
//构造方法
public CRUD(Context context) {
//实例化SQLiteOpenHelper
dbHandler = new NoteDatabase(context);
}
//对数据库进行写入功能
public void open() {
db = dbHandler.getWritableDatabase();
}
//关闭数据库
public void close() {
dbHandler.close();
}
//添加数据加入到database里面
public Note addNote(Note note) {
//添加一个笔记到数据库
//专门处理数据的一个类,相当于一个内容值
ContentValues contentValues = new ContentValues();
contentValues.put(NoteDatabase.CONTENT, note.getContent());
contentValues.put(NoteDatabase.TIME, note.getTime());
contentValues.put(NoteDatabase.MODE, note.getTog());
long insertId = db.insert(NoteDatabase.TABLE_NAME, null, contentValues);
note.setId(insertId);
return note;
}
//通过id获取数据
public Note getNote(long id) {
Cursor cursor = db.query(NoteDatabase.TABLE_NAME, columns, NoteDatabase.ID + "=?", new String[]{String.valueOf(id)}, null, null, null);
if (cursor != null) cursor.moveToFirst();
Note note = new Note(cursor.getString(1), cursor.getString(2), cursor.getInt(3));
return note;
}
//通过id获取所有数据
public List<Note> getAllNotes() {
Cursor cursor = db.query(NoteDatabase.TABLE_NAME, columns, null, null, null, null, null);
List<Note> list = new ArrayList<>();
Note note = null;
if (cursor.getCount() > 0) {
while (cursor.moveToNext()) {
note = new Note();
note.setId(cursor.getLong(cursor.getColumnIndex(NoteDatabase.ID)));
note.setContent(cursor.getString(cursor.getColumnIndex(NoteDatabase.CONTENT)));
note.setTime(cursor.getString(cursor.getColumnIndex(NoteDatabase.TIME)));
note.setTog(cursor.getInt(cursor.getColumnIndex(NoteDatabase.MODE)));
list.add(note);
}
}
return list;
}
//修改数据
public int updateNote(Note note) {
ContentValues values = new ContentValues();
values.put(NoteDatabase.CONTENT, note.getContent());
values.put(NoteDatabase.TIME, note.getTime());
values.put(NoteDatabase.MODE, note.getTog());
return db.update(NoteDatabase.TABLE_NAME, values,
NoteDatabase.ID + "=?", new String[]{String.valueOf(note.getId())});
}
//删除数据
public void removeNote(Note note) {
db.delete(NoteDatabase.TABLE_NAME, NoteDatabase.ID + "=" + note.getId(), null);
}
}
三、监听事件和基于事件回调的事件处理机制(捞干的说)
监听事件处理机制
首先我们需要了解监听的三要素:
⭐️Event Source事件源
⭐️Event事件
⭐️Event Listener事件监听器
下面我们用一个例子展示什么是监听器
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG,"点击了事件");
//这里补充说明一下Log.d就是在debug那里打印,有很多朋友找不到日志打哪里去了
}
});
实现监听的方法
ps:由于考虑文章的延展性,网上这些资料也很多,就不在这里写代码了
1.通过内部类实现
2.通过匿名内部类实现
3.通过事件源所在类实现
4.通过外部类实现(就是在外面建一个java类)
5.布局中的onClick属性(就是在布局xml文件中设置onClick(),记得绑定public方法)
基于回调的事件处理机制
重点:1.回调机制与监听机制的区别. 2.基于回调的事件传播
研究背景:想象一下,目前我们在Activity中绑定了一个控件,然后点击这个控件,我们触发回调。
此时,回调的顺序是:先从控件本身回调,然后,继续执行Activity回调
思考:为什么点击控件会,触发两次回调,回调为什么会传播
观察代码:发现:在回调函数事件方法最后,我们都使用了return false。
当将Activity中的return false修改为return true,此时,将不处罚Activity的回调事件
因为,才是其被消费掉了,不会回调(官话叫,该组件已经对事件进行处理,不用调用其他组件的分发方法了)
结论:事件方法最后如果return false,事件会继续传播,且事件是由内向外传播的(官话叫,该组件不能对事件进行处理,需要按照规则继续分发事件)
事件方法最后如果return true,就代表在本层消费完毕,不会继续传播(官话叫,该组件已经对事件进行处理,不用调用其他组件的分发方法了)
监听执行的顺序,优于回调先执行
研究这个监听和回调有什么用?
监听和回调可以在开发中有效的代替组件之间的传值问题。
例:比如,3个组件之间的传值,组件A、B、C
A是一个Activity,B是一个Fragment依赖于A,C也是一个Fragment依赖于B
此时,如果B直接向C传值,使用bundle方法,可能消耗更多资源。
在这里,我们就可以在B中设置回调方法传值给A,设置监听,通过监听数据的变化,将值传递给C。
emmm,我给你拉出来一个,给你们看看
Fragment-动态添加碎片
private void replaceFragment(Fragment fragment){
FragmentManager fragmentManager = getSupportFragmentMannager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.right_layout,fragment);
transaction.addToBackStack(null); //补充:接收一个名字用于描述返回栈的状态(就是点back程序不会退出,而是回到上一个fragment)
transaction.commit();
}
//总结:
//1.创建待添加碎片,就是new一个fragment
//2.获取FragmentManager,可以直接在activity中getSupportFragmentMannager()调取
//3.开启一个事务,通过调用beginTransaction()方法开启
//4.向容器内添加或替换碎片,一般用replace()方法,其中需要传入容器id和待添加的碎片实例
//5.提交事务,调用commit()
他就是要一直replace,替换替换,传值很麻烦,如果部替换,值传过不去,生命周期只能走一次。
四、ListView
思路:ListView顾名思义,一个列表罢了。
做一个ListView大致就是,先在布局中添加一个ListView,作为容器。
然后把要在列表中重复显示的布局内容写出来。
接下来,想让列表内容,添加到ListView布局中,就需要创建一个适配器(Adapter),去管理ListView的内容(这就是适配器的内容之一啦).
然后数据的话,得有一个实体类(entity)。
最后,在Activity或者Fragment文件把他加载出来就行啦。
RecyclerView
这个比ListView功能强大一点。
这个可以支持横向列表和瀑布流布局。
开发一般用这个多一点吧,学完ListView看这个就行,他俩差不多。
五、网络
WebView
作用:
1.加载URL(网络或者本地assets文件夹下的html文件)
2.加载html代码
3.Native和javaScript相互调用
WebView加载URL
WebView加载网络URL
方法:webview.loadUrl(“http://www.baidu.com”);
WebView加载assets下的html文件
方法:webview.loadUrl(“file://android_asset/test.html”);
WebView加载html代码
方法:webview.loadwData();
webview.loadDataWithBaseURL();
网页的前进和后退
⭐️webview.canGoBack()
⭐️webview.goBack()
⭐️webview.canGoForward()
⭐️webview.goForward()
⭐️webview.canGoBackOrForward(int steps)
[注意]:按下返回键,默认是退出当前Activity,如果希望是WebView内页面后退
@Override
public boolean onKeyDown(int keyCode,KeyEvent event){
if((keyCode == KeyEvent.KEYCODE_BACE) && webView.canGoBack()){
webView.goBack();
return true;
}
return super.onKeyDown(keyCode,event)
}
//这个代码只能写在Activity里面,不能写在fragment里面,如果想在Fragment里面做,去网上搜,我看到过
WebView实例代码
public class EmmmmFragment extends BaseFragment {
@BindView(R.id.web_V)
WebView webV;
Unbinder unbinder;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_working_emmmm, container, false);
unbinder = ButterKnife.bind(this, view);
//让他默认可以加载js
webV.getSettings().setJavaScriptEnabled(true);
//让他可以跳转页面
webV.setWebViewClient(new MyWebViewClient());
webV.setWebChromeClient(new MyWebChromeClient());
//这里难搞啊,我看的视频是https://www.m.baidu.com这样写的,但是我这样写报错,于是就下面这样了
webV.loadUrl("https://www.baidu.com");
return view;
}
class MyWebViewClient extends WebViewClient{
@Override
public boolean shouldOverrideUrlLoading(WebView webV, WebResourceRequest request){
webCalender.loadUrl(request.getUrl().toString());
return super.shouldOverrideUrlLoading(webCalender,request);
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
Log.d("webView","onPageFinished...");
}
}
class MyWebChromeClient extends WebChromeClient{
@Override
public void onProgressChanged(WebView webV, int newProgress) {
super.onProgressChanged(webCalender, newProgress);
}
@Override
public void onReceivedTitle(WebView webCalender, String title) {
super.onReceivedTitle(webCalender, title);
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
}
网络请求
HttpURLConnection
URL url = new UPL("http://www.baidu.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//设置请求类型
connection.setRequestMethod("GET"); //发送GET请求 GET/POST
//设置请求超时
connection.setConnectTimeout(8000);//时间毫秒值
connection.setReadTimeout(8000);
//获取服务器返回的输入流
InputStream in = connection.getInputStream();
//关闭HTTP
connection.disconnect();
//读取返回流的值
reader = new BufferedReader(new InputStreamReader(in));
StringBuilder response = new StringBuilder();
String line;
While((line = reader.readLine()) !==null ){
response.append(line);
}
showResponse(response.toString());
看完这个然后可以学一下OkHttp,学完这个就可以学习比较流行的网络请求框架啦,然后就可以用了,入门新手的话,应该不至于让你做这个吧,做的话网上很多例子,查查就差不多,我感觉,应该写不出一朵花。
六、认识一些项目文件
一般都是做着做着就都知道了,也没必要太系统的学一遍
AndroidMainfest.xml文件
简述:1.程序中定义的所有四大组件,都需要在这个文件里注册
2.给应用程序添加权限声明
其中:
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
这两行代码所在Activity,表示此Activity是主活动,点开本程序的入口
build.gradle文件
build.gradle(Project)
buildscript {
repositories {
jcenter() //代码托管仓库
}
dependencies {
classpath "com.android.tools.build:gradle:7.0.2"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31"
//声明gradle插件
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
build.gradle(Module)
plugins {
id 'com.android.application' //这是一个应用程序模块
id 'com.android.library' //这是一个库模块
}
android {
compileSdk 31 //指定项目的编译版本
defaultConfig {
applicationId "com.co.test" //指定项目包名
minSdk 26 //指定项目最低兼容Android系统版本
targetSdk 31 //运行时权限
versionCode 1 //项目版本号
versionName "1.0" //项目版本名
}
buildTypes { //用于指定安装文件的相关配置
release { //正式
minifyEnabled false //是否对项目代码进行混淆
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' //指定混淆时使用的规则文件
}
debug { //测试
minifyEnabled false
}
}
dependencies { //指定项目所有的依赖关系 1.本地依赖 2.库依赖 3.远程依赖
//需要啥用啥就是了。。。
}
END 详细总结
作者也是一个刚入门的小白- -
也在做一些学习的总结,一些详细的代码和做法,在下面这两篇文章有喔,还有一些经验