Android Studio第一行代码 第三章注意事项

3.2 常用控件

 TextView

  TextView 的文字对齐方式,默认是左上角对齐android:gravity 来指定文字的对齐方式,可选值有 top、bottom、left、right、center等 , 可 以 用 “ | ” 来 同 时 指 定 多 个 值
android:gravity="center"
TextView 中文字的大小和颜色进行修改
android:textSize="24sp"
android:textColor="#00ff00"
TextView 中文本内容进行修改
android:text="This is TextView"
Button
禁用英文字母大写转换         Android:textAllCaps="false"
使用匿名类的方式来注册监听器
public class MainActivity extends Activity {
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 在此处添加逻辑
}
});
}
}
使用实现接口的方式来进行注册监听器
public class MainActivity extends Activity implements OnClickListener {
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
// 在此处添加逻辑
break;
default:
break;
}
}
}
EditText
android:hint="这是提示性文本"
android:maxLines="2"
android:maxLines 指定了 EditText 的最大行数为两行
ImageView
ProgressBar 进度条
默认是圆型进度条
<ProgressBar
    android:id="@+id/progress_bar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    style="?android:attr/progressBarStyleHorizontal"
    android:max="100"
    />

style="?android:attr/progressBarStyleHorizontal" 水平进度条

AlertDialog  

//确认对话框
AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
dialog.setTitle("This is Dialog");
dialog.setMessage("Something important.");
dialog.setCancelable(false);
dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) { }
});
dialog.setNegativeButton("Cancel", new DialogInterface.
        OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) { }
});
dialog.show();
//对话框进度条
ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setTitle("This is ProgressDialog");
progressDialog.setMessage("Loading...");
progressDialog.setCancelable(true);
progressDialog.show();

3.3 四种布局

线性布局  

android:orientation="vertical"   垂直方向   高度不能指定为 match_parent

android:orientation=" horizontal" 水平方向   宽度不能指定为 match_parent

文字在控件中的对齐方式:android:layout_gravity

android:layout_gravity="center_vertical

<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:text="Button 1" />
三种对齐方式  top, center_vertical, bottom。
android:layout_weight。这个属性允许我们使用比例的方式来指定控件的大小,使用前要将android:layout_width置为0.
系统会先把 LinearLayout 下所有控件指定的 layout_weight 值相加,得到一个总值,
然后每个控件所占大小的比例就是用该控件的 layout_weight 值除以刚才算出的总值。因此如
果想让 EditText 占据屏幕宽度的 3/5 Button 占据屏幕宽度的 2/5 ,只需要将 EditText
layout_weight 改成 3 Button layout_weight 改成 2 就可以了。
<EditText
android:id="@+id/input_message"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Type something"
/>
RelativeLayout 相对布局
android:layout_alignParentLeft 、和父布局左对齐
android:layout_alignParentTop 、顶
android:layout_alignParentRight 、右对齐
android:layout_alignParentBottom 、底
android:layout_centerInParent 中间
android:layout_above 属性可以让一个控件位于另一个控件的上方,android:layout_below 表示让一个控件位于另一个控件的下方,android:layout_toLeftOf 表示让 一个控件位于另一个控件的左侧,android:layout_toRightOf 表示让一个控件位于另一个控件的右侧。
注意,当一个控件去引用另一个控件的 id 时,该控件一定要定义在引用控件的后面,不然会出现找不到 id 的情况。
FrameLayout 帧布局
布局没有任何的定位方式,所有的控件都会摆放在布局的左上角。
TableLayout 表格布局
android:layout_span="2"  占两列空间  (合并表格)
android:stretchColumns 的值指定为 1 ,表示如果表格不能完全占满屏幕宽度,就将第二列进行拉伸。没错!指定成 1 就是拉伸第二列,指定成 0 就是拉伸第一列(拉伸表格)
AbsoluteLayout 绝对布局
引入布局
想创建一个标题栏布局,可以通过引入布局解决大量代码重复。
android:background 用于为布局或控件指定一个背景,可以使用颜色或图片来进行填充,
先在layout中新建一个布局 title.xml,在程序中使用这个标题栏需要修改activity_main.xml 中的代码, 不管有多少布局需要添加标题栏,只需一行 include 语句就可以了。
<include layout="@layout/title" />
最后要记得要将  MainActivity 中将系统自带的标题栏隐藏掉,
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
}
}

3.4 自定义控件

新建 TitleLayout 继承自 LinearLayout ,让它成为我们自定义的标题栏控件,代码如下所示:
public class TitleLayout extends LinearLayout {
public TitleLayout(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater.from(context).inflate(R.layout.title, this);
}
}
通过 LayoutInflater from() 方法可以构建出一个 LayoutInflater对象,然后调用 inflate() 方法就可以动态加载一个布局文件, inflate() 方法接收两个参数,第一个参数是要加载的布局文件的 id ,这里我们传入 R.layout.title ,第二个参数是给加载好的布局再添加一个父布局,这里我们想要指定为 TitleLayout ,于是直接传入 this
125
自定义控件创建好后,我们需要在布局文件中添加这个自定义控件,修改activity_main.xml 中的代码,如下所示:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.uicustomviews.TitleLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
></com.example.uicustomviews.TitleLayout>
</LinearLayout>

3.5 ListView

Android 中提供了很多适配器的实现类,其中 ArrayAdapter 可以通过泛型来指定要适配的数据类型,然后在构造函数中把要适配的数据传入即可。
ArrayAdapter<String> adapter =
new ArrayAdapter<String>( MainActivity.this , android.R.layout.simple_list_item_1 , data );
ArrayAdapter 的构造函数中依次传入 当前上下文 ListView 子项布局的 id ,以及 要适配的数据
getView() 方法中还有一个 convertView 参数,这个参数用于将之前加载好的布局进行缓存,以便之后可以进行重用。视图复用机制(View recycling),以提高性能和减少内存使用。
View view;
if (convertView == null){            //没有旧视图可供复用
    view = LayoutInflater.from(getContext()).inflate(resourceId, null);    //创建新试图
} else {
    view = convertView;    //复用旧试图
}
在view = LayoutInflater.from(getContext()).inflate(resourceId, null);

LayoutInflater 创建一个新的视图实例。resourceId 是要加载的布局资源的 ID。inflate 方法的第二个参数 null,表示不将新创建的视图附加到根视图上。实际开发中,最好将第二个参数设置为 parent,并将第三个参数设置为 false,以确保视图层级正确。

view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);

提升运行效率

新增了一个内部类 ViewHolder ,用于对控件的实例进行缓存。当 convertView 为空
的时候,创建一个 ViewHolder 对象,并将控件的实例都存放在 ViewHolder 里,然后调用 View
setTag() 方法,将 ViewHolder 对象存储在 View 中。当 convertView 不为空的时候则调用
View getTag() 方法,把 ViewHolder 重新取出。这样所有控件的实例都缓存在了 ViewHolder
里,就没有必要每次都通过 findViewById() 方法来获取控件实例了。
   ViewHolder viewHolder = null;
            if (convertView == null) {
                view = LayoutInflater.from(getContext()).inflate(resourceId, null);
                viewHolder = new ViewHolder();
                viewHolder.fruitImage = (ImageView) view.findViewById
                        (R.id.fruit_image);
                viewHolder.fruitName = (TextView) view.findViewById
                        (R.id.fruit_name);
                view.setTag(viewHolder); // 将ViewHolder存储在View中 } else {
                view = convertView;
                viewHolder = (ViewHolder) view.getTag(); // 重新获取ViewHolder
            }
            viewHolder.fruitImage.setImageResource(fruit.getImageId());
            viewHolder.fruitName.setText(fruit.getName());

添加点击事件(在MainActivity的onCreate中)

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                                    int position, long id) {
                Fruit fruit = fruitList.get(position);
                Toast.makeText(MainActivity.this, fruit.getName(),
                        Toast.LENGTH_SHORT).show();
            }
        });

3.6 单位和尺寸

px 是像素
pt 是磅数的意思, 1 磅等于 1/72 英寸,一般 pt 都会作为字体的单位来使用。
dp 是密度无关像素的意思,也被称作 dip ,和 px 相比,它在不同密度的屏幕中的显示比例将保持一致。
sp 是可伸缩像素的意思,它采用了和 dp 同样的设计理念,解决了文字大小的适配问题。
因此,使用 dp 来指定控件的宽和高,就可以保证控件在不同密度的屏幕中的显示比例保持一致
使用 sp 来指定文字的宽和高,就可以保证文字在不同密度的屏幕中的显示比例保持一致

3.7 编写界面实践

制作Nine-Patch 图片

如果在 Android sdk 目录下没有 tools 文件夹,或没找到 draw9patch.bat 文件。(可能原因是新版sdk已经移除,整合到了AS中)打开AndroidStudio,选中后缀为png的图片,右键,下滑后即可看到 Creat 9-Patch File。

制作步骤可参考启动图制作:Android Studio制作.9.png图亲测详细流程之每步图解-CSDN博客

简单来说就是  勾选showpaches,适当放大zoom,再按照上下左右(也可不按,怎么方便怎么做)的顺序设置非拉伸区。如设置上方时,鼠标从左边框向右拉伸到刚过图形圆弧处松开,再从右边框向左拉伸到刚过圆弧处。这样上方设置完成,接着按相同方法设置其他方向就行。

图片设置好后,把原来的message_left.png删除,只保留message_left.9.png。以免引用时冲突报错。

  <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/message_left" >
    </LinearLayout>

聊天界面

MainActivity


import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;

import androidx.appcompat.app.AppCompatActivity;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private ListView msgListView;

    private EditText inputText;

    private Button send;

    private MsgAdapter adapter;

    private List<Msg> msgList = new ArrayList<Msg>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        initMsgs();
        adapter = new MsgAdapter(MainActivity.this, R.layout.msg_item, msgList);
        inputText = (EditText) findViewById(R.id.input_text);
        send = (Button) findViewById(R.id.send);
        msgListView = (ListView) findViewById(R.id.msg_list_view);
        msgListView.setAdapter(adapter);
        send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String content = inputText.getText().toString();
                if (!"".equals(content)) {
                    Msg msg = new Msg(content, Msg.TYPE_SENT);
                    msgList.add(msg);
                    adapter.notifyDataSetChanged();
                    msgListView.setSelection(msgList.size());
                    inputText.setText("");
                }
            }
        });
    }

    private void initMsgs() {
        Msg msg1 = new Msg("Hello guy.", Msg.TYPE_RECEIVED);
        msgList.add(msg1);
        Msg msg2 = new Msg("Hello. Who is that?", Msg.TYPE_SENT);
        msgList.add(msg2);
        Msg msg3 = new Msg("This is Tom. Nice talking to you. ", Msg.TYPE_RECEIVED);
        msgList.add(msg3);
    }

}

Msg


public class Msg {
    public static final int TYPE_RECEIVED = 0;
    public static final int TYPE_SENT = 1;
    private String content;
    private int type;
    public Msg(String content, int type) {
        this.content = content;
        this.type = type;
    }
    public String getContent() {
        return content;
    }
    public int getType() {
        return type;
    } }

MsgAdapter


import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.List;

public class MsgAdapter extends ArrayAdapter<Msg> {
    private int resourceId;
    public MsgAdapter(Context context, int textViewResourceId, List<Msg>
            objects) {
        super(context, textViewResourceId, objects);
        resourceId = textViewResourceId;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Msg msg = getItem(position);
        View view;
        ViewHolder viewHolder;
        if (convertView == null) {
            view = LayoutInflater.from(getContext()).inflate(resourceId, null);
            viewHolder = new ViewHolder();
            viewHolder.leftLayout = (LinearLayout) view.findViewById
                    (R.id.left_layout);
            viewHolder.rightLayout = (LinearLayout) view.findViewById
                    (R.id.right_layout);
            viewHolder.leftMsg = (TextView) view.findViewById(R.id.left_msg);
            viewHolder.rightMsg = (TextView) view.findViewById(R.id.right_msg);
            view.setTag(viewHolder);
        } else {
            view = convertView;
            viewHolder = (ViewHolder) view.getTag();
        }
        if (msg.getType() == Msg.TYPE_RECEIVED) {
// 如果是收到的消息,则显示左边的消息布局,将右边的消息布局隐藏
            viewHolder.leftLayout.setVisibility(View.VISIBLE);viewHolder.rightLayout.setVisibility(View.GONE);
            viewHolder.leftMsg.setText(msg.getContent());
        } else if(msg.getType() == Msg.TYPE_SENT) {
// 如果是发出的消息,则显示右边的消息布局,将左边的消息布局隐藏
            viewHolder.rightLayout.setVisibility(View.VISIBLE);
            viewHolder.leftLayout.setVisibility(View.GONE);
            viewHolder.rightMsg.setText(msg.getContent());
        }
        return view;
    }
    class ViewHolder {
        LinearLayout leftLayout;
        LinearLayout rightLayout;
        TextView leftMsg;
        TextView rightMsg;
    } }

activity_main.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:background="#d8e0e8"
    android:orientation="vertical" >
    <ListView
        android:id="@+id/msg_list_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:divider="#0000" >
    </ListView>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
        <EditText
            android:id="@+id/input_text"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:hint="Type somthing here"
            android:maxLines="2" />
        <Button
            android:id="@+id/send"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Send" />
    </LinearLayout>
</LinearLayout>

msg_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="vertical"
    android:padding="10dp" >
    <LinearLayout
        android:id="@+id/left_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="left"
        android:background="@drawable/message_left" >
        <TextView
            android:id="@+id/left_msg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_margin="10dp"
            android:textColor="#fff" />
    </LinearLayout>
    <LinearLayout
        android:id="@+id/right_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:background="@drawable/message_right" >
        <TextView
            android:id="@+id/right_msg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_margin="10dp" />
    </LinearLayout>
</LinearLayout>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值