分享

再次快速入门编写APP

 beginnow1 2022-09-22 发布于广东
好几年前学了java编写过一个类似微信聊天界面的,聊天机器人。当时学完java已经就没耐心从头开始学安卓了,就直接了解个基础的东西,再需要什么API,实现方法,直接百度东拼西凑完成了自己的第一个图灵+百度语音APP,我的android分类里有相关文章,有兴趣可以去看看。现在可好当初没记录现在都忘光光了,java也基本忘了。搭建环境还是挺简单的,主要还是网络问题,能有个好的代理网站就简单了,教程也很多就不讲了

先从基本的android代码结构开始吧,推荐网页

https://blog.csdn.net/weixin_49770443/article/details/116935303

故屿

工程项目三个重要文件:

1.MainActivity.java
2.activity_main.xml (布局文件)
3.AndroidManifest.xml (安卓配置文件)

也有对这几个文件的基本结构功能做了分析,可以去看原文章

Activity活动的生命周期

还有个值得了解的,Activity活动的生命周期,像是onCreate方法是点击APP开始第一个进入的,可以写些初始化的操作。但是控件之类的,在setContentView(R.layout.activity_main);方法之后才能调用,不然组件都没加载就用,会导致闪退,没有相应权限调用方法一样会闪退,别问我为什么知道的。

Android Activity 生命周期的状态图。

https://developer.android.google.cn/guide/components/activities/activity-lifecycle

所以首先需要声明好权限,我这就不多说了,我另一篇有讲以蓝牙的为例。

搭建APP界面

了解完基础知识之后,就可以开始搭建APP啦,点击AndroidManifest.xml开始布局自己的界面,我还是习惯用右上角的design界面,直接编辑界面,这才是编辑前端的正确打开方式吗,毕竟我也是新手。

有两个比较使用的布局组件,LinearLayout(线性布局)跟 constraintlayout(约束布局),线性布局可以在竖向或横向的堆叠方式,约束布局可以随意拖拽约束跟四周控件的距离,也十分方便,可以在component Tree里右键组件添加约束条件。

比较重要的控件参数

android:id="@+id/textView"   //程序调用的入口名字

android:layout_width="match_parent"  //跟随父类的大小

android:layout_height="wrap_content" //自适应大小

android:layout_weight="0.8"   //控件大小的占比,

//适合多控件之间分配比例,来适应不同屏幕

我的app界面代码如下,类似聊天窗口,我是用来做蓝牙调试助手的。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas./apk/res/android"
    xmlns:app="http://schemas./apk/res-auto"
    xmlns:tools="http://schemas./tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">



    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="80dp"
        android:lineSpacingExtra="2dp"
        android:fadeScrollbars="false"
        android:scrollbars="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.0" />



    <LinearLayout
        android:id="@+id/linearLayout"
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:orientation="horizontal"
        app:layout_constraintBottom_toBottomOf="parent">

        <EditText
            android:id="@+id/editText"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:autofillHints=""
            android:hint="@string/editText"
            android:textColorHint="#757575" />

        <Button
            android:id="@+id/sentButton"
            android:layout_width="120dp"
            android:layout_height="match_parent"
            android:layout_marginBottom="0dp"
            android:text="@string/sent" />
    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

常用组件控件

常用的组件有Button(按键)、TextView(文本框)、EditText(编辑框)、ListView(列表视图)

控件都需要先声明,再初始化,就可以调用相应控件方法啦。

    Button sentButton;
    TextView textView;
    EditText editText;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sentButton = (Button) findViewById(R.id.sentButton);
        textView = (TextView) findViewById(R.id.textView);
        editText = (EditText) findViewById(R.id.editText);
        //按键监听
        sentButton.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                //按键按下处理代码
            }
        });

在界面代码也看到,我在TextView里加了这两行代码,

android:fadeScrollbars="false"    //显示滚动条

android:scrollbars="vertical"       //垂直方向滚动

再程序里面加上一句,textView.setMovementMethod(ScrollingMovementMethod.getInstance());  //设置滚动

便能实现TextView的文本过多滚动显示

最后贴上MainActivity.java的代码

package com.example.bt_communication;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.content.pm.PackageManager;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;

import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    //先声明,实例化
    Button sentButton;
    TextView textView;
    EditText editText;

    //textview实现消息自动滚动
    private void refreshScrollPosition(){
        int line = textView.getLineCount();
        if (line > 33) {//超出屏幕自动滚动显示(33是当前页面显示的最大行数)
            //textView.getLineHeight(),中文跟字母的高度大小不一致,中文会有位置不对的bug
            int offset = textView.getLineCount() * textView.getLineHeight();
            textView.scrollTo(0, offset - textView.getHeight() );
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //控件初始化,匹配控件ID
        sentButton = (Button) findViewById(R.id.sentButton);
        textView = (TextView) findViewById(R.id.textView);
        editText = (EditText) findViewById(R.id.editText);
        textView.setMovementMethod(ScrollingMovementMethod.getInstance());  //设置滚动
        //确认权限
        Permission permission = new Permission();
        permission.checkPermissions(this);

        //按键监听
        sentButton.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                String inputText = editText.getText().toString();
                textView.setText(inputText);   //直接设置覆盖文本框的内容
                Toast.makeText(MainActivity.this, inputText, Toast.LENGTH_SHORT).show();  //弹出文本通知
                Log.d(TAG,"inputText:" + inputText + '\n');  //打印debug类型的log
                textView.append(inputText + '\n');  //将文本添加到文本框加换行
                refreshScrollPosition();
            }
        });
    }

    //权限申请声明
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == Permission.RequestCode) {
            for (int i = 0; i < grantResults.length; i++) {
                if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                    Log.e("p","拒绝的权限名称:" + permissions[i]);
                    Log.e("p","拒绝的权限结果:" + grantResults[i]);
                    Log.e("p","有权限未授权,可以弹框出来,让客户去手机设置界面授权。。。");
                }else {
                    Log.e("p","授权的权限名称:" + permissions[i]);
                    Log.e("p","授权的权限结果:" + grantResults[i]);
                }
            }
        }
    }

}

最后可以用android studio下方的Logcat来调试自己的代码,log.d之类的方法会打印信息在里面

1、选上自己的程序(默认选上还是会跑出一堆系统的打印的)

2、可以选上不同的打印类型,可是还会打印更高级的log信息

3、选择不同的过滤方式,也可以自定义

  

问题:Attempt to invoke virtual method '.......' on a null object reference

出现空指针的话,确定初始化的步骤是否正确,控件findViewById初始化需要在onCreate函数里,而且而且在setContentView(R.layout.activity_main);之后。

    Button sentButton;
    TextView textView;
    EditText editText;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sentButton = (Button) findViewById(R.id.sentButton);
        textView = (TextView) findViewById(R.id.textView);
        editText = (EditText) findViewById(R.id.editText);
        sentButton.setcgListener(new View.cgListener() {
            @Override
            public void cg(View view) {

            }
        });

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多