软件开发过程中,界面设计和功能开发同样重要。Android中有多种编写程序界面的方式可供选择。接下来学习一下Android的UI开发。

文章目录

  • 常见UI控件
    • TextView
    • Button
    • EditText
    • ImageView
    • ProgressBar
    • Android控件的可见属性
    • AlertDialog
    • ProgressDialog
  • 基本布局
    • 线性布局
    • 相对布局
    • 帧布局
  • 自定义控件
    • 引入布局
    • 创建自定义控件
  • ListView
    • 基本使用
    • 定制ListView
    • 优化ListView
    • 点击事件
  • RecyclerView
    • 添加RecyclerView
    • 基本用法
    • 点击事件
  • 开发Tips

常见UI控件

TextView

TextView是Android中最简单的一个控件,它主要用于在界面上显示一段文本信息。<TextView>标签有以下这些属性:

  • andriod:id :给当前控件定义一个唯一标识符。
  • android:layout_width :指定控件的宽度。
    android:layout_height :指定控件的高度。
    Android中所有控件都有这两个属性,有三个可选值:
  • match_parent:表示让当前控件的大小和父布局的大小一样,也就是由父布局来决定当前控件的大小。
  • fill_parent:与match_parent意义相同,官方推荐使用match_parent。
  • wrap_content:表示让当前控件的大小能够刚好包含住里面的内容,也就是由控件内容决定当前控件的大小。
  • android:text :指定TextView中显示的文本内容。
  • android:gravity :指定文字的对齐方式,可选值有top 、bottom 、left、right 、center 等,可以用“|”来同时指定多个值。
  • android:textSize :指定文字大小。Android中字体大小使用sp作为单位。
  • android:textColor :指定文字的颜色。
  • android:layout_gravity :用于指定控件在布局中的对齐方式,可选值和android:gravity差不多
  • android:background :为布局或控件指定一个背景,可以使用颜色或图片来进行填充
  • android:layout_margin :指定控件在上下左右方向上偏移的距离

以上属性都是所有控件都拥有的。

Button

Button(按钮)用于与用户进行交互,<Button>标签中除了共有属性,还有下面这个属性:

  • android:textAllCaps:指定系统是否将Button中的英文字母自动进行大写转换,默认为true。

在界面上定义了一个Button控件还不够,还需要将Button的点击事件注册一个监听器,如下代码所示:

Button button = (Button) findViewById(R.id.bottom);
button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//点击按钮的逻辑}
});
  • 通过findViewById()方法获取到在布局文件中定义的元素。findViewById()方法返回的是一个View对象,需要向下转型将它转成Button对象。
  • 通过调用setOnClickListener()方法为按钮注册一个监听器,点击按钮时就会执行监听器中的onClick()方法。监听器有两种构建方式,一种就是上述代码通过View.OnClickListener接口的匿名内部类来构建,还有一种方式,就是实现View.OnClickListener接口,代码如下所示:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button button = (Button) findViewById(R.id.button);button.setOnClickListener(this);}@Overridepublic void onClick(View v) {// 在此处添加逻辑}
}

EditText

EditText允许用户在控件里输入和编辑内容,并可以在程序中对这些内容进行处理。除了通用属性,<EditText>标签还有这些属性:

  • android:hint:指定一段提示性的文本。当输入任何内容时,这段文本就会自动消失。
  • android:maxLines:限制EditText最大行数
  • android:maxHeight:限制EditText最大高度
  • android:maxLength:限制EditText最大长度
  • android:maxWidth:限制EditText最大宽度

可通过如下代码来获得EditText的实例,获取EditText中的内容,然后进行相关操作:

EditText editText = (EditText) findViewById(R.id.edit_text);
String text = editText.getText().toString();

ImageView

ImageView是用于在界面上展示图片的一个控件,图片通常都是放在以“drawable”开头的目录下的。<ImageView>标签中除了通用属性,还有android:src属性,这个属性给ImageView指定了一张图片。
android:scaleType属性用于指定图片的缩放方式,常用的值有:

  • centerCrop:使图片保持原有比例填充ImageView,使,图片最短边长度与ImageView边的长度相等,并将超出的部分裁剪掉,图片居中
  • center:使图片在视图中居中,但不缩放。
  • centerInside:使图片保持原有比例填充ImageView,图片最长边长度与ImageView边的长度相等,图片居中

可通过以下代码获取ImageView实例,进行相关的操作:

ImageView imageView = (ImageView) findViewById(R.id.image_view);
imageView.setImageResource(R.drawable.img);

ImageView的setImageResource()方法将显示的图片改成指定的图片,可用于动态变换图片。

ProgressBar

ProgressBar用于在界面上显示一个进度条,表示程序正在加载一些数据。除了通用属性,<ProgressBar>标签中还有这些属性:

  • style:指定进度条的样式
  • android:max:给进度条设置一个最大值

通过代码可以动态更改进度条的进度,如下所示:

ProgressBar progressBar = (ProgressBar) findViewById(R.id.progress_bar);
int progress = progressBar.getProgress();
progress = progress + 10;
progressBar.setProgress(progress);

Android控件的可见属性

在所有的Android控件中除了上面的通用属性,还有可见属性:android:visibility,这个属性有三个值:

  • visible:表示控件是可见的,这个值是默认值,不指定android:visibility 时,控件都是可见的。
  • invisible:表示控件不可见,但是它仍然占据着原来的位置和大小,可以理解成控件变成透明状态了。
  • gone:则表示控件不仅不可见,而且不再占用任何屏幕空间。

除了在xml文件中可以设置控件的可见性,还可以通过代码来设置控件可见性:

//以ProgressBar为例,获取控件实例然后设置控件可见性
ProgressBar progressBar = (ProgressBar) findViewById(R.id.progress_bar);
//获取控件可见性
progressBar.getVisibility();
progressBar.setVisibility(View.VISIBLE);
//progressBar.setVisibility(View.INVISIBLE);
//progressBar.setVisibility(View.GONE);

getVisibility();方法用于获取控件的可见性,对应的值为:View.VISIBLE,View.INVISIBLE,View.GONE。

AlertDialog

AlertDialog在当前的界面弹出一个对话框,这个对话框是置顶于所有界面元素之上的,能够屏蔽掉其他控件的交互能力,因此AlertDialog一般都是用于提示一些非常重要的内容或者警告信息。相关代码如下所示:

AlertDialog.Builder dialog = new AlertDialog.Builder (MainActivity.this);
dialog.setTitle("This is Dialog");
dialog.setMessage("Something");
dialog.setCancelable(false);
dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {}
});
dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {}
});
dialog.show();

创建AlterDialog实例通过AlertDialog.Builder()来创建,传入当前Activity。AlterDialog常见方法:

  • setTitle():设置对话框标题。
  • setMessage():设置对话框的内容。
  • setCancelable():可否用Back键关闭对话框。
  • setPositiveButton():为对话框设置确定按钮的点击事件。这个方法有两个参数,一个是确认按钮的名称,一个是监听事件。
  • setNegativeButton():设置取消按钮的点击事件。这个方法有两个参数,一个是取消按钮的名称,一个是监听事件。
  • show():显示对话框。

ProgressDialog

ProgressDialog是AlterDialog的子类,功能与AlterDialog相似,不同点在于ProgressDialog会在对话框中显示一个进度条,一般用于表示当前操作比较耗时,让用户耐心地等待。这个类在API level 26 中,ProgressDialog被声明不赞成使用,应使用的替代方法是ProgressBar。
ProgressDialog用法与AlterDialog类似,如下所示:

ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setTitle("This is ProgressDialog");
progressDialog.setMessage("Loading...");
progressDialog.setCancelable(true);
progressDialog.show();

PS:如果在setCancelable()中传入了false,表示ProgressDialog是不能通过Back键取消掉。这时一定要在代码中做好控制,当数据加载完成后必须要调用ProgressDialog的dismiss()方法来关闭对话框,否则ProgressDialog将会一直存在。

基本布局

布局是一种可用于放置很多控件的容器,它可以按照一定的规律调整内部控件的位置,从而编写出精美的界面。布局和控件关系如下图所示

线性布局

LinearLayout称作线性布局,是一种非常常用的布局,这个布局会将它所包含的控件在线性方向上依次排列。<ProgressBar>标签通过android:orientation属性指定排列方向,可选值有两个:

  1. vertical:控件沿垂直方向排列。
  2. horizontal:控件沿水平方向排列,默认的排列方式。

Tips:

  • 如果LinearLayout的排列方向是horizontal,内部的控件就绝对不能将宽度指定为match_parent,因为这样的话,单独一个控件就会将整个水平方向占满,其他的控件就没有可放置的位置了。同样的道理,如果LinearLayout的排列方向是vertical,内部的控件就不能将高度指定为match_parent。
  • 当布局中的控件指定了android:layout_gravity这个属性,LinearLayout的排列方向是horizontal时,只有垂直方向上的对齐方式才会生效,因为此时水平方向上的长度是不固定的,每添加一个控件,水平方向上的长度都会改变,因而无法指定该方向上的对齐方式。同样的道理,当LinearLayout的排列方向是vertical时,只有水平方向上的对齐方式才会生效。

LinearLayout中控件还有一个重要属性android:layout_weight,这个属性使用比例的方式来指定控件的大小,它在手机屏幕的适配性方面可以起到非常重要的作用。如下所示

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="match_parent"><EditTextandroid:id="@+id/input_message"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:hint="Type something"/><!--PS:dp是Android中用于指定控件大小、间距等属性的单位--><Buttonandroid:id="@+id/send"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="Send"/>
</LinearLayout>

使用了android:layout_weight 属性,此时控件的宽度就不应该再由android:layout_width 来决定,这里指定成0dp是一种比较规范的写法。

android:layout_weight如何控制控件大小:系统会先把LinearLayout下所有控件指定的layout_weight值相加,得到一个总值,然后每个控件所占大小的比例就是用该控件的layout_weight值除以刚才算出的总值。

相对布局

RelativeLayout又称作相对布局,也是一种非常常用的布局。RelativeLayout可以通过相对定位的方式让控件出现在布局的任何位置。
在RelativeLayout布局下,控件属性也有非常多:

  • android:layout_alignParentLeft:是否使控件位于父布局左侧(true or false)
  • android:layout_alignParentTop:是否使控件位于父布局顶部(true or false)
  • android:layout_alignParentRight:是否使控件位于父布局右侧(true or false)
  • android:layout_alignParentBottom:是否使控件位于父布局底部(true or false)
  • android:layout_centerInParent:是否使控件位于父布局中间(true or false)
  • android:layout_above:让一个控件位于另一个控件的上方,需要为这个属性指定相对控件id的引用(当一个控件去引用另一个控件的id时,该控件一定要定义在引用控件的后面,不然会出现找不到id的情况)
  • android:layout_below:让一个控件位于另一个控件的下方,需要为这个属性指定相对控件id的引用
  • android:layout_toLeftOf:表示让一个控件位于另一个控件的左侧,需要为这个属性指定相对控件id的引用
  • android:layout_toRightOf:表示让一个控件位于另一个控件的右侧,需要为这个属性指定相对控件id的引用
  • android:layout_alignLeft:让一个控件的左边缘和另一个控件的左边缘对齐
  • android:layout_alignRight:让一个控件的右边缘和另一个控件的右边缘对齐
  • android:layout_alignTop:让一个控件的上边缘和另一个控件的上边缘对齐
  • android:layout_alignBottom:让一个控件的下边缘和另一个控件的下边缘对齐
  • 。。。。。。

RelativeLayout属性较多,可通过属性名称来判断该属性对控件的定位

帧布局

FrameLayout又称作帧布局,它的应用场景少很多。这种布局没有方便的定位方式,所有的控件都会默认摆放在布局的左上角。
可以使用layout_gravity属性来指定控件在布局中的对齐方式,这和LinearLayout中的用法是相似的。

自定义控件

所有控件都是直接或间接继承自View的,所有布局都是直接或间接继承自ViewGroup的。

View是Android中最基本的一种UI组件,它可以在屏幕上绘制一块矩形区域,并能响应这块区域的各种事件,Android的各种控件其实就是在View的基础之上又添加了各自特有的功能。而ViewGroup则是一种特殊的View,它可以包含很多子View和子ViewGroup,是一个用于放置控件和布局的容器。

引入布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent" ><include layout="@layout/title" />
</LinearLayout>

在一个布局文件中引入另外一个布局文件,使用<include>标签,在layout属性填入要引入的布局id。

若引入的布局是标题栏,还需要将系统自带的标题栏隐藏,隐藏代码如下:

ActionBar actionbar = getSupportActionBar();
if (actionbar != null) {actionbar.hide();
}
  • getSupportActionBar()方法来获得ActionBar的实例
  • hide()方法将标题栏隐藏起来

创建自定义控件

自定义控件能解决系统控件不能满足实际需求,重复代码的问题。

以自定义标题栏为例,自定义标题栏控件,代码如下:

public class TitleLayout extends LinearLayout {public TitleLayout(Context context, AttributeSet attrs) {super(context, attrs);LayoutInflater.from(context).inflate(R.layout.title, this);//添加其他相关逻辑}
}

新建一个类继承View或者View的子类,然后重写构造方法,在构造方法中添加响应的逻辑(还可以重写View中的其他方法)。使用LayoutInflater的from()方法可以构建出一个LayoutInflater 对象,然后调用inflate()方法就可以动态加载一个布局文件。
inflate() 方法接收两个参数:

  1. 第一个参数是要加载的布局文件的id
  2. 第二个参数是给加载好的布局再添加一个父布局

创建好自定义布局之后,需要在需要在其他布局中引用自定义布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><cn.chenjianlink.android.uicustomviews.TitleLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"/></LinearLayout>

添加自定义控件和添加普通控件的方式基本是一样的,只不过在添加自定义控件的时候,需要指明控件的完整类名,包名不可以省略。

ListView

程序中有大量的数据需要展示的时候,可以借助ListView来实现。

基本使用

在Activity布局文件中引入ListView控件

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><ListViewandroid:id="@+id/List_view"android:layout_width="match_parent"android:layout_height="match_parent" /></androidx.constraintlayout.widget.ConstraintLayout>

ListView是用于展示大量数据的,这些数据一般是数组或者是集合,无法直接导入到ListView中,需要借助适配器来导入数据。一般使用的是ArrayAdapter。它可以通过泛型来指定要适配的数据类型,然后在构造函数中把要适配的数据传入。在ArrayAdapter的构造函数中依次传入当前上下文、ListView子项布局的id,以及要适配的数据。

 ArrayAdapter(@NonNull Context context, @LayoutRes int resource, @NonNull T[] objects)  ArrayAdapter(@NonNull Context context, @LayoutRes int resource, @NonNull List<T> objects)

构造好适配器对象后,获取ListView实例,调用ListView的setAdapter() 方法,将构建好的适配器对象传递进去。这样ListView就能显示数据了

定制ListView

官方提供的ListView界面不一定能满足需求,可以自己定制一个。

定制ListView官方提供的适配器可能就不好用了,需要自定义一个适配器。适配器可通过继承ArrayAdapter或是其父类来实现。

@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {View view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);//添加相关逻辑
}
  • 一般要重写getView方法。这个方法在每个子项被滚动到屏幕内的时候会被调用。
  • 使用LayoutInflater来指定每个子项的布局文件
  • getContext()获取当前Activity
  • 一旦View有了父布局之后,它就不能再添加到ListView中了,所以LayoutInflater的inflate()方法的第三个参数设置为false。
  • convertView这个参数用于将之前加载好的布局进行缓存,可以之后进行重用(可以判断convertView是否为空,若为空,则使用LayoutInflater去加载布局,若不为空,则直接重用)

优化ListView

  • getView(int position, @Nullable View convertView, @NonNull ViewGroup parent),判断convertView是否为空,来进行优化
  • 新建一个ViewHolder类来对控件实例进行缓存,调用View的getTag()方法将ViewHolder存进View中,使用getTag()方法获取ViewHolder对象

点击事件

setOnItemClickListener()方法为ListView注册了一个监听器,当用户点击了ListView中的任何一个子项时,就会回调onItemClick()方法

ListView listView = (ListView) findViewById(R.id.List_view);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {//添加相关逻辑}
});

RecyclerView

RecyclerView是一个增强版的ListView,不仅可以轻松实现和ListView同样的效果,还优化了ListView中存在的各种不足之处。目前Android官方更加推荐使用RecyclerView。

添加RecyclerView

RecyclerView属于新增控件,需要在build.gradle文件中添加相应的依赖库,由于AndroidSDK在高版本出现变动,所以添加的依赖有些不同,AndroidSDK版本在28及以上以及Gradle版本为4.6及以上时,dependencies闭包添加如下内容

dependencies {implementation fileTree(dir: 'libs', include: ['*.jar'])implementation 'androidx.appcompat:appcompat:1.1.0'implementation 'androidx.constraintlayout:constraintlayout:1.1.3'testImplementation 'junit:junit:4.12'androidTestImplementation 'androidx.test:runner:1.2.0'androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'implementation 'androidx.recyclerview:recyclerview:1.0.0'
}

在AndroidSdk版本在28以下以及Gradle版本为4.6以下时,dependencies闭包添加如下内容

dependencies {compile fileTree(dir: 'libs', include: ['*.jar'])compile 'com.android.support:appcompat-v7:24.2.1'compile 'com.android.support:recyclerview-v7:24.2.1'testCompile 'junit:junit:4.12'
}

基本用法

在布局文件中引入RecyclerView,AndroidSDK版本在28及以上以及Gradle版本为4.6及以上时,使用以下代码引入RecyclerView:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recycler_view"android:layout_width="match_parent"android:layout_height="match_parent"/></LinearLayout>

在AndroidSdk版本在28以下以及Gradle版本为4.6以下时使用以下标签引入RecyclerView:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><android.support.v7.widget.RecyclerViewandroid:id="@+id/recycler_view"android:layout_width="match_parent"android:layout_height="match_parent" /></LinearLayout>

引入RecyclerView后,需要给RecyclerView配置一个适配器,新建一个适配器,让这个适配器继承RecyclerView.Adapter类,相关代码如下:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {static class ViewHolder extends RecyclerView.ViewHolder {View MyView;public ViewHolder(@NonNull View itemView) {super(itemView);//构建ViewHolder的相关逻辑}}@NonNull@Overridepublic ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.My_item, parent, false);final ViewHolder holder = new ViewHolder(view);//相关逻辑//......return holder;}@Overridepublic void onBindViewHolder(@NonNull ViewHolder holder, int position) {//相关逻辑}@Overridepublic int getItemCount() {//相关逻辑}
}
  • 定义一个内部类ViewHolder,ViewHolder要继承自RecyclerView.ViewHolder。然后ViewHolder的构造函数中要传入一个View参数,这个参数通常就是RecyclerView子项的最外层布局。
  • onCreateViewHolder()、onBindViewHolder()和getItemCount()这三个方法必须重写
  • onCreateViewHolder()方法用于创建ViewHolder实例
  • onBindViewHolder()方法是用于对RecyclerView子项的数据进行赋值的,会在每个子项被滚动到屏幕内的时候执行
  • getItemCount()方法返回RecyclerView一共有多少子项

适配器准备好之后,需要在Activity中进行必要设置:

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);//下面这句代码是设置布局滚动方向linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);recyclerView.setLayoutManager(linearLayoutManager);MyAdapter adapter = new MyAdapter();recyclerView.setAdapter(adapter);//其他逻辑}
}
  • 获取RecyclerView实例,然后创建布局管理器以及适配器,并将这两者绑定到RecyclerView实例中
  • LinearLayoutManager用于指定RecyclerView为线性布局,可实现和ListView一样的效果。可通过LinearLayoutManager的setOrientation()方法来设置布局的排列方向,默认是纵向排列,默认值为LinearLayoutManager.VERTICAL。要设置成横向排列,则传入LinearLayoutManager.HORIZONTAL。
  • ListView的布局排列是由自身去管理的,而RecyclerView则将布局排列交给了LayoutManager,LayoutManager中制定了一套可扩展的布局排列接口,子类只要按照接口的规范来实现,就能定制出各种不同排列方式的布局。除了LinearLayoutManager,RecyclerView还提供了GridLayoutManager(网格布局)和StaggeredGridLayoutManager(瀑布流布局)这两种内置的布局排列方式。
    使用瀑布流布局代码如下:
 @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);recyclerView.setLayoutManager(layoutManager);FruitAdapter adapter = new FruitAdapter(fruitList);recyclerView.setAdapter(adapter);}

StaggeredGridLayoutManager的构造函数接收两个参数,第一个参数用于指定布局的列数;第二个参数用于指定布局的排列方向,传入StaggeredGridLayoutManager.VERTICAL表示会让布局纵向排列(传入StaggeredGridLayoutManager.HORIZONTAL表示让布局横向排列),最后再把创建好的实例设置到RecyclerView当中就可以了

点击事件

RecyclerView并没有提供类似于setOnItemClickListener()这样的注册监听器方法,而是需要自行给子项具体的View去注册点击事件,相比于ListView来说,实现起来要复杂一些。这么做的好处是,当点击的是子项里具体的某一个按钮,实现起来比较简单,而ListView实现这个就很困难了。

开发Tips

使用Nine-Patch图片指定图片可被拉伸的部分,防止图片因为拉伸而失真。

Android学习羁绊之UI设计相关推荐

  1. Android学习——5个UI界面设计

    Android学习--5个UI界面设计 一.计算器 二.frameLayout(框架布局)实现登录界面 三.RelativeLayout相对布局实现登录界面 四.表格布局 五.多布局 一.计算器 &l ...

  2. Android学习之登陆界面设计(一)前后期准备以及相关配置

    Android学习之登陆界面设计(一)前后期准备以及相关配置 前言 成品 成品样式 成品特点 工具 系统配置 手机配置 Android Studio 3.6.3 SDK 图片来源 矢量图标库 Back ...

  3. Android学习之登陆界面设计(二)基本界面设计

    Android学习之登陆界面设计(二)基本界面设计 前提 绘图样式 - drawable bg_login_btn_submit.xml bg_login_panel_slide.xml bg_log ...

  4. android ui设计与开发工具,Android用户体验与UI设计

    Android用户体验与UI设计 编辑 锁定 讨论 上传视频 本词条缺少概述图,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧! 本书是一部介绍Android用户体验.UI设计理念和方法论的作品 ...

  5. UI设计师需要学习哪些知识?UI设计零基础怎么入门?

    本文由:"学设计上兔课网"原创,图片素材来自网络,仅供学习分享 UI设计师需要学习哪些知识?UI设计零基础怎么入门?很多初学设计的小伙伴都不是很了解ui,觉得UI设计及时做界面.做 ...

  6. Android学习羁绊之Activity

    原文链接:Android学习羁绊–>Activity Activity是Android系统的四大组件之一,Activity是用户可操作的可视化界面,为用户提供一个完成操作指令的窗口,一个Acti ...

  7. 在Android上部署深度学习模型之UI设计(七)

    导读 前面介绍了一些Android相关的配置文件,这篇文章我们主要来介绍一下Android UI设计相关的知识,如何来设计界UI. Android的布局 Android的UI主要是利用布局结合控件来设 ...

  8. android逻辑分辨率,手机ui设计dpi如何把握,看这3个平台各自的画布设置情况

    智能手机的发展可以说是当下科技发展的趋势之一,在智能手机的发展过程中,APP的开发是关键.而dpi是影响APP设计的重要因素之一.今天就让小编为大家介绍手机ui设计dpi如何把握. 手机ui设计dpi ...

  9. Android Studio完成简单UI设计

    目录 一.五个简单UI设计: a.双击打开activity main.xml b.添加辅助线 c.添加按钮输入框: 二.TextView图文混排 三.修改不同颜色的按钮 四.设计CheckBox和ra ...

最新文章

  1. ×××S 2012 聚合函数 -- 介绍
  2. Linux下使用iotop检测磁盘io使用情况
  3. spring 两次进入拦截器_spring mvc 拦截器一次请求拦截两次?
  4. AndroidStudio_安卓原生开发_java.io.FileNotFoundException: http://172.19.128.5(拒绝访问)---Android原生开发工作笔记157
  5. java.net.SocketException: Write failed: Broken pipe异常分析
  6. 混淆矩阵(TP+FN+FP+TN)
  7. android学习之ListView如何使用
  8. 疑似 B 站后台源码泄露,ikun 潜入?
  9. NB-iot的M5310A的学习
  10. SCSI代码分析(3)SCSI设备的管理2
  11. vue 下载文件,文件损坏无法打开
  12. 双目视觉摄像机的参数标定参考坐标系介绍
  13. xshell支持图形_Xshell打不开图形化界面,或许该这样做!
  14. w7计算机u盘在哪里,win7电脑无法发现u盘怎么解决
  15. android sina 微博表情功能的实现
  16. TortoiseGit配置ppk的密钥
  17. linux运行维护缺口,Linux运维工程师人才缺口巨大,或成2018年热门职位
  18. PHP imagecreate - 生成自定义图片
  19. bootstrap设计横线上加字
  20. INTERSPEECH 2022 | 钉钉蜂鸣鸟音频实验室论文入选国际顶会,创新提出窄带滤波网络架构

热门文章

  1. Excel如何实现表单编号自动递增?
  2. Linux 信号大全
  3. 【PA2012】【BZOJ3502】Tanie linie
  4. 《基于改进YOLOv5的无人机图像检测算法》论文阅读
  5. 军犬舆情每日热点:iPhone迎史上最大优惠;我国成功发射通讯技术试验卫星
  6. datatables实现分页
  7. r语言x c(-1 -2),R语言apply系列介绍
  8. python链接微信接口开发教程_Python调用微信公众平台接口操作示例
  9. 近百单神秘外卖被送至多地消防队 留言暖心
  10. 就业关注:“80年代大学生”的十大职场尴尬