Android UI开发

本文主要探讨了Android UI开发中的关键点,包括常用的控件、四种布局的详细解析,以及如何创建和加载自定义控件。布局作为界面设计的基础,通过嵌套能够构造复杂界面。同时,介绍了自定义控件的创建,所有控件和布局都基于View或ViewGroup进行扩展,自定义控件的引入和创建步骤也进行了讲解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一,常用的控件

1.TextView 用来显示文本内容  在LinearLayout中可以指定属性 
		文字对齐方式  android:gravity (top, center ....)
		文字颜色 android:textColor
		文字大小 android:textSize="24sp"   以sp为单位
	
2.Button  用来显示按钮
		防止切换大小写  android:textAllCaps="false"
		注册监听按钮:  Button titleEdit = (Button)findViewById(R.id.title_edit);

        titleBack.setOnClickListener( new OnClickListener(){
            @Override
            public void onClick(View v) {
                ( (Activity) getContext()).finish();

            }
        });
 
3.EditText  用来和用户进行文本交互的控件
	加入输入提示信息 android:hint="Type something important"
	指定EditText的最大行数 android:maxLines="2" 当文本长度超过两行就会向上滚动
	获取文本的内容  getText().toString();

4.imageView 是用来在界面上展示图片
	在res目录下新建文件件drawable-xhdpi目录  然后将图片文件放入文件夹
	指定图片文件 android:src="@drawable/img_1" 
	动态的更改图片 ImageView image = (ImageView)findViewById( R.id.image_view );
									image.setImageResource(R.drawable.img_2 );
									
5.ProcessBar  进度条表示我们的程序正在加载一些数据
	所有的android控件都有3种属性 visable invisable  gone 使用setVisibility()方法
	if( progressBar.getVisibility() == View.GONE){
				progressBar.setVisibility( View.VISIBLE );
		}else{
				processBar.setVisibility( View.GONE );
			}
		设置为长条形的进度条  style="?android:attr/progressBarStyleHorizontal"
													android:max="100"
			int progress = progressBar.getProgress();
			progress = progress + 10;
			progressBar.setProgress(progress);

6.AlertDialog 这个对话框是置顶于所有界面元素之上的,能够屏蔽掉其他控件的交互能力,一般用来提示重要内容

		AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this );
		dialog.setMessage("....");
		dialog.setTitle(".......");
		dialog.setCancelable( false);
		dialog.setPositiveButton( "OK", new DialogInterface.OnClickListener(){ ....} );
		dialog.setNegativeButton( "CANCEL", new DialogInterface.OnClickListener(){ ....} );
	
	调用show(); 显示对话框。
	
7.ProcessDialog  和AlertDialog类似 能够屏蔽掉其他控件的交互能力,一般用来表示耗时操作让用户耐心的等待
			  ProgressDialog progressDialog = new ProgressDialog( MainActivity.this );
        progressDialog.setTitle("this is progressDialog");
        progressDialog.setMessage("Loading...");
        progressDialog.setCancelable(true);
        progressDialog.show();
 

二,详解四种布局

    布局是一种可以放置很多控件的容器,还可以放置布局,通过嵌套可以完成一些比较复杂的界面实现

1.线性布局(LinearLayout)

    可以通过android:orientation属性指定排列方向 (vertical 或者是 horizontal )
    android:layout_gravity  和 android:gravity   前者指定的是控件在布局中的对齐方式, 后者指定的是文字在控件中的对齐方式
   	可选项有(top center_vertical	bottom left right 等)
   	center_horizontal:将对象横向居中,不改变其大小。水平对齐方式:水平方向上居中对齐。
   	只有LinearLayout 允许使layout_weight 实现按比例指定控件大小的功能
   	android:layout_weight  允许使用比例布局
   	android:layout_width = "0dp"
   	android:layout_height = "wrap_content"
   	android:layout_weight="1"
 
 2.相对布局(RelativeLayout)
 		可以通过相对定位的方式让空间出现在布局的任何位置
 		android:layout_alignParentLeft
 		android:layout_alignParentRight
 		android:layout_alignParentTop
 		android:layout_alignParentBottom
 		android:layout_centerInparent
 		
 		相对于控件的引用
 		android:layout_below="@id/buttom1"
 		android:layout_above
 		android:layout_toLeftOf
 		android:layout_toRightOf
 		
 		控件对齐
 		android:layout_alignLeft   表示让一个控件的左边缘和另一个控件的左边缘对齐
 		android:layout_alignRight   同上
 		android:layout_alignTop			同上
 		android:layout_alignBottom  同上
 3.帧布局(FrameLayout)
 	这种布局没有方便的定位方式,所有的控件都会默认摆放在布局的左上角
 	可以使用android:layout_gravity 指定控件的对齐方式 "left" "right" 等等
 
 4.百分比布局
 	  百分比布局只为FrameLayout和RelativeLayout提供扩展功能
 	  PercentFrameLayout PercentRelativeLayout
 	  可以使用属性 layout_widthPercent  layout_heightPercent		layout_gravity="left|top"  ....


三,创建和加载自定义控件

    所有的控件都是直接或者间接继承自View的,所有的布局都是直接或者间接继承自ViewGroup的。  ViewGroup是一种特殊的View,他可以包含很多子View和子ViewGroup,是一个用于放置控件和布局的容器

1.引入布局

 1.先创建要引入的布局
 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
     android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/title">
    <Button
        android:id="@+id/title_back"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="5dp"
        android:background="@drawable/by"
        android:text="Back"
        android:textColor="#fff"/>
    <TextView
        android:id="@+id/title_text"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_weight="1"
        android:gravity="center"
        android:text="Title Text"
        android:textColor="#fff"
        android:textSize="24sp"/>
    <Button
        android:id="@+id/title_edit"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="5dp"
        android:background="@drawable/bn"
        android:text="Edit"
        android:textColor="#fff"/>
</LinearLayout>

在需要引入该布局的xml文件中加入语句
			<include layout="@layout/title"/>
	然后在活动中将系统自带的标题栏隐藏掉
		代码如下
		ActionBar actionBar = getSupportActionBar();
        if( actionBar != null){
            actionBar.hide();
        }

2.创建自定义控件

1.创建自定义标题栏控件,为刚才的布局添加相应函数
public class TitleLayout extends LinearLayout {
    public TitleLayout(Context context, AttributeSet attributes){
        super( context, attributes);
        LayoutInflater.from( context).inflate( R.layout.title, this );
        Button titleBack = (Button)findViewById(R.id.title_back);
        Button titleEdit = (Button)findViewById(R.id.title_edit);

        titleBack.setOnClickListener( new OnClickListener(){
            @Override
            public void onClick(View v) {
                ( (Activity) getContext()).finish();

            }
        });
        titleEdit.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText( getContext(), "clicked Edit button", Toast.LENGTH_SHORT).show();
            }
        });
    }
}
2.在布局文件中添加这个自定义控件(一定要指定完整的类名,包在这里是不可以省略的)
<com.example.wangyamin.uicustomviews.TitleLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
四,ListView控件
	当程序中有大量的数据需要展示的是时候,可以借助 ListView来实现。ListView允许使用手指将屏幕外的数据滑动到屏幕内并展示
	新建活动 修改里面的activity_main.xml 代码设置ListView
	
	数组中的数据是无法直接传递给ListView的需要借助适配器,最后调用setAdapter()方法   这样数据和ListView之间的联系就建立完成了
	
	自定义ListView界面
	1.新建水果类
	package com.example.wangyamin.listviewtest;

/**
 * Created by wangyamin on 2018/3/22.
 */

public class Fruit {
    private  String name;
    private int imageId;
    public Fruit( String name, int imageId ){
        this.name = name;
        this.imageId = imageId;
    }
    public String getName(){
        return name;
    }

    public int getImageId() {
        return imageId;
    }
}

	2.创建水果的布局
	<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/fruit_image"
        android:layout_width="80dp"
        android:layout_height="80dp" />

    <TextView
        android:id="@+id/fruit_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="10dp"/>
</LinearLayout>
	3.创建水果的适配器
	/**
 * Created by wangyamin on 2018/3/22.
 */

public class FruitAdapter extends ArrayAdapter {
    private  int resourceId;
    public  FruitAdapter(Context context, int textViewResourceID, List<Fruit> objects ){
        super( context, textViewResourceID, objects);
        resourceId = textViewResourceID;
    }

    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent){
        Fruit fruit = (Fruit) getItem( position );
        View view;
        ViewHolder viewHolder;
//        View view = LayoutInflater.from( getContext()).inflate( resourceId, parent, false );
        if ( convertView == null ){
            view = LayoutInflater.from(getContext()).inflate( resourceId, parent,false );
            viewHolder = new ViewHolder();
            viewHolder.fruitImage = (ImageView)view.findViewById(R.id.fruit_image);
            viewHolder.fruitName   = (TextView)view.findViewById(R.id.fruit_name);
            view.setTag( viewHolder);
        }
        else{
            view = convertView;
            viewHolder = (ViewHolder)view.getTag();
        }
      /*  ImageView fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
        TextView    fruitName = (TextView)view.findViewById(R.id.fruit_name);
        fruitImage.setImageResource( fruit.getImageId());
        fruitName.setText( fruit.getName() );*/
        viewHolder.fruitImage.setImageResource( fruit.getImageId() );
        viewHolder.fruitName.setText(fruit.getName());
        return view;
    }
    class  ViewHolder{
        ImageView fruitImage;
        TextView fruitName;
    }
}
	4.将数据和ListView建立联系
	public class MainActivity extends AppCompatActivity {
    private String[] data = { "caomei", "huolongguo","li","lingmeng", "mihoutao","pingguo",
                                "taozi","xiangjiao","xihonghsi","yangmei","yingtao"};
    private List<Fruit> fruitList = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initFruits();
        FruitAdapter adapter = new FruitAdapter(MainActivity.this, R.layout.fruit_item, fruitList);
        //     ArrayAdapter<String> adapter = new ArrayAdapter<String>( MainActivity.this,android.R.layout.simple_list_item_1,data);
        ListView listView = (ListView) findViewById(R.id.list_view);
        listView.setAdapter(adapter);
        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();
            }
        });
    }
    private void initFruits(){
        for( int i = 0; i< 2; i++ ){
            Fruit caomei = new Fruit( "caomei",R.drawable.caomei );
            fruitList.add( caomei );

            Fruit huolongguo = new Fruit( "huonongguo", R.drawable.huolongguo );
            fruitList.add( huolongguo );

            Fruit li = new Fruit( "li", R.drawable.li );
            fruitList.add( li );

            Fruit linmeng = new Fruit( "linmeng", R.drawable.linmeng );
            fruitList.add( linmeng );

            Fruit mihoutao = new Fruit( "mihoutao", R.drawable.mihoutao );
            fruitList.add( mihoutao );

            Fruit pingguo = new Fruit( "pingguo", R.drawable.pingguo );
            fruitList.add( pingguo );

            Fruit taozi = new Fruit( "taozi", R.drawable.taozi );
            fruitList.add( taozi );

            Fruit xiangjiao = new Fruit( "xiangjiao", R.drawable.xiangjiao );
            fruitList.add( xiangjiao );

            Fruit xihongshi = new Fruit( "xihongshi", R.drawable.xihongshi );
            fruitList.add( xihongshi );

            Fruit yangmei = new Fruit( "yangmei", R.drawable.yangmei );
            fruitList.add( yangmei );

            Fruit yingtao = new Fruit( "yingtao", R.drawable.yingtao );
            fruitList.add( yingtao );

        }
    }
}
	
	提升ListView的运行效率, getView() 方法中还有一个convertView 参数 可以将已经加载的布局缓存, 新增ViewHolder对控件实例缓存
	
五,更强大的控件RecyclerView
	1.RecyclerView这个控件不仅可以实现在垂直方向上的滚动,还可以实现在水平方向上的滚动
	2.还可以为RecyclerView设定布局管理器  LinearLayoutManger GridLayoutLayoutManger  StaggeredGridLayoutManger 
	
	要想使用这个控件就先要在app/build.gradl导入 
	compile'com.android.support:recyclerview-v7:26.1.0'
	1.添加RecycleView布局, 这里需要使用完整的类名
	<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.wangyamin.recyclerview.MainActivity">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

</LinearLayout>

2.为RecyclerView准备一个适配器 新建FruitAdapter类,让其继承RecyclerView.Adapter(必须重写onCreateViewHolder() onBindViewHolder() 和getItemCount()这三个方法) 并将泛型指定为FruitAdapter.ViewHolder,
/**
 * Created by wangyamin on 2018/3/22.
 */

public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {

    private List<Fruit> mFruitList;
    public class ViewHolder extends  RecyclerView.ViewHolder {
        View fruitView;
        ImageView fruitImage;
        TextView fruitName;
        public ViewHolder( View view){
           super(view);
           fruitView = view;
            fruitImage = (ImageView) view.findViewById( R.id.fruit_image);
            fruitName = (TextView)view.findViewById(R.id.fruit_name);
        }
    }

    public FruitAdapter( List<Fruit> fruitList){
        mFruitList = fruitList;
    }

    //鐩稿綋浜庡缓绔嬩竴涓ā鏉?
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from( parent.getContext() ).inflate( R.layout.fruit_item, parent,false);
        final  ViewHolder holder = new ViewHolder( view );
        holder.fruitView.setOnClickListener( new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                int position = holder.getAdapterPosition();
                Fruit fruit = mFruitList.get(position);
                Toast.makeText( v.getContext(),"you clieck view"+ fruit.getName(), Toast.LENGTH_SHORT).show();
            }
        });
        holder.fruitImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int position = holder.getAdapterPosition();
                Fruit fruit = mFruitList.get(position);
                Toast.makeText( v.getContext(),"you clieck img"+ fruit.getName(), Toast.LENGTH_SHORT).show();
            }
        });
        holder.fruitName.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int position = holder.getAdapterPosition();
                Fruit fruit = mFruitList.get(position);
                Toast.makeText( v.getContext(),"you clieck text"+ fruit.getName(), Toast.LENGTH_SHORT).show();
            }
        });
        return  holder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Fruit fruit = mFruitList.get(position);
        holder.fruitImage.setImageResource( fruit.getImageId());
        holder.fruitName.setText( fruit.getName());
    }


    @Override
    public int getItemCount() {
        return  mFruitList.size();
    }
}

3.修改MainActivity让RecycleView和数据通过适配器建立联系
public class MainActivity extends AppCompatActivity {

    private List<Fruit> fruitList = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initFruits();
        RecyclerView recyclerView = (RecyclerView)findViewById( R.id.recycler_view );
       // LinearLayoutManager layoutManager = new LinearLayoutManager( this );
       // layoutManager.setOrientation( LinearLayoutManager.HORIZONTAL);
       // GridLayoutManager gridLayoutManager = new GridLayoutManager( this,3 );
        StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager( 3,StaggeredGridLayoutManager.VERTICAL);
      //  staggeredGridLayoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);
        recyclerView.setLayoutManager( layoutManager );
     //   staggeredGridLayoutManager.addItemDecoration(new GridSpacingItemDecoration(40));
        FruitAdapter adapter = new FruitAdapter( fruitList );
        recyclerView.setAdapter( adapter );
    }
    public void initFruits(){
        for( int i =0 ; i <3 ; i++){
            Fruit caomei = new Fruit( getRandomLengthName("caomei"),R.drawable.caomei );
            fruitList.add( caomei );

            Fruit huolongguo = new Fruit( getRandomLengthName("huolongguo"), R.drawable.huolongguo );
            fruitList.add( huolongguo );

            Fruit li = new Fruit( getRandomLengthName("Fruit"), R.drawable.li );
            fruitList.add( li );

            Fruit linmeng = new Fruit( getRandomLengthName("linmeng"), R.drawable.linmeng );
            fruitList.add( linmeng );

            Fruit mihoutao = new Fruit( getRandomLengthName("mihoutao"), R.drawable.mihoutao );
            fruitList.add( mihoutao );

            Fruit pingguo = new Fruit( getRandomLengthName("pingguo"), R.drawable.pingguo );
            fruitList.add( pingguo );

            Fruit taozi = new Fruit( getRandomLengthName("taozi"), R.drawable.taozi );
            fruitList.add( taozi );

            Fruit xiangjiao = new Fruit( getRandomLengthName("xiangjiao"), R.drawable.xiangjiao );
            fruitList.add( xiangjiao );

            Fruit xihongshi = new Fruit( getRandomLengthName("xihongshi"), R.drawable.xihongshi );
            fruitList.add( xihongshi );

            Fruit yangmei = new Fruit( getRandomLengthName("yangmei"), R.drawable.yangmei );
            fruitList.add( yangmei );

            Fruit yingtao = new Fruit( getRandomLengthName("yingtao"), R.drawable.yingtao );
            fruitList.add( yingtao );
        }
    }

    private String getRandomLengthName( String name){
        Random random = new Random();
        int length = random.nextInt(20) +1;
        StringBuilder builder =new StringBuilder();
        for( int i = 0; i <length;i++ ){
            builder.append(name);
        }
        return builder.toString();
    }
}




    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值