四、安卓UI学习(2)

UI布局

LinearLayout

常见属性:

//或者vertical
android:orientation="horizontal"

这里需要注意,如果 LinearLayout 的排列方向是 horizontal,内部的控件就绝对不能将宽度指定为 match_parent,因为这样的话单独一个控件就会将整个水平方向占满,其他的控件就没有可放置的位置了。同样的道理,如果 LinearLayout 的排列方向是 vertical,内部的控件就不能将高度指定为 match_parent

gravity

top 
center_vertical
bottom
...
android:layoutgravity="top"

案例:

//horizontal的情况下
   <Button 
       android:id="@+id/button1"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_gravity="top"
       android:text="Button 1"
       />
   <Button 
       android:id="@+id/button2"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_gravity="center_vertical"
       android:text="Button 2"
       />
   <Button 
       android:id="@+id/button3"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Button 3"
       android:layout_gravity="bottom"
       />

这里写图片描述
控件的比例分配:

//0dp是规范写法
    <EditText 
        android:id="@+id/input_message"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:hint="Type something"
        />

    <Button 
        android:id="@+id/send"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Send"
        />

这里写图片描述

指定部分权重:
Button会按照自己的宽度来,EditText会占满剩下的空间

<EditText 
    android:id="@+id/input_message"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:hint="Type something"
    />

<Button 
    android:id="@+id/send"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Send"
    />

这里写图片描述

RelativeLayout

<Button 
   android:id="@+id/button1"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_alignParentLeft="true"
   android:layout_alignParentTop="true"
   android:text="Button 1"
   />
<Button 
   android:id="@+id/button2"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_alignParentRight="true"
   android:layout_alignParentTop="true"
   android:text="Button 2"
   />
<Button 
   android:id="@+id/button3"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_centerInParent="true"
   android:text="Button 3"
   />
<Button 
   android:id="@+id/button4"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_alignParentBottom="true"
   android:layout_alignParentLeft="true"
   android:text="Button 4"
   />
<Button 
   android:id="@+id/button5"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_alignParentBottom="true"
   android:layout_alignParentRight="true"
   android:text="Button 5"
   />

这里写图片描述

<Button 
    android:id="@+id/button3"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:text="Button 3"
   />
<Button 
    android:id="@+id/button1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toLeftOf="@id/button3"
    android:layout_above="@id/button3"
    android:text="Button 1"
   />
<Button 
    android:id="@+id/button2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toRightOf="@id/button3"
    android:layout_above="@id/button3"
    android:text="Button 2"
   />
<Button 
    android:id="@+id/button4"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toLeftOf="@id/button3"
    android:layout_below="@id/button3"
    android:text="Button 4"
   />
<Button 
    android:id="@+id/button5"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toRightOf="@id/button3"
    android:layout_below="@id/button3"
    android:text="Button 5"
   />

这里写图片描述

FrameLayout

 <Button 
     android:id="@+id/button"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:text="Button"
     />
 <ImageView
     android:id="@+id/image_view"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:src="@drawable/ic_launcher"
     />

这里写图片描述

TabelLayout

<TableRow >
    <TextView 
        android:layout_height="wrap_content"
        android:text="Account:"
        />
    <EditText 
        android:id="@+id/account"
        android:layout_height="wrap_content"
        android:hint="Input your account"
        />
</TableRow>

<TableRow >

    <TextView 
        android:layout_height="wrap_content"
        android:text="Password:"
        />
    <EditText 
        android:id="@+id/password"
        android:layout_height="wrap_content"
        android:inputType="textPassword"
        />
</TableRow>

<TableRow >
    <Button 
        android:id="@+id/login"
        android:layout_height="wrap_content"
        android:layout_span="2"
        android:text="Login"
        />

</TableRow>

这里写图片描述

这样不怎么美观,可以加上属性

android:stretchColumns="1"

表示如果没占满就拉伸控件
这里写图片描述

引入布局

//主页面加入,onCreate里面关闭title
<include layout="@layout/title" />

创建自定义控件

这里写图片描述
上面的三个控件的背景是自定义的图片
新建title.xml:

//linear里面:
android:background="@drawable/title_bg"
<Button
    android:id="@+id/title_back"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="5dip"
    android:background="@drawable/back_bg"
    android:gravity="center"
    android:text="Back"
    android:textColor="#fff" 
    />

<TextView
    android:id="@+id/title_text"
    android:layout_width="0dip"
    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="5dip"
    android:background="@drawable/edit_bg"
    android:text="Edit"
    android:textColor="#fff" 
    />

新键TitleLayout ,继承LinearLayout:

public class TitleLayout extends LinearLayout {

    public TitleLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        LayoutInflater.from(context).inflate(R.layout.title, this);
    }

}

修改activity_main中的代码:
实际上这个代码跟上面的引用布局一样,不过这里以类名识别

   <com.example.uilayouttest.TitleLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       ></com.example.uilayouttest.TitleLayout>

修改TitleLayout:

    public TitleLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        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 arg0) {
                // TODO Auto-generated method stub
                ((Activity)getContext()).finish();
            }
        });
        titleEdit.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                Toast.makeText(getContext(), "You clicked Edit button", Toast.LENGTH_SHORT);
            }
        });
    }
}

ListView

activity里面:

 <ListView 
     android:id="@+id/list_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent"    
     ></ListView>

MainActivity里面:

private String[] data = {"Apple", "Banana", "Orange", "Watermelon", 
        "Pear", "Grape", "Pineapple", "Strawberry", "Cherry", "Mango"
};

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
       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

加上图片和文字
新建水果类:

package com.example.listviewtest;

public class Fruit {
    private String name;
    private int imageId;

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

}

新建布局fruit_item:

<ImageView 
    android:id="@+id/fruit_image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    />

<TextView 
    android:id="@+id/fruit_name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:layout_marginLeft="10dip"
    />

新建FruitAdatper:

private int resourceId;

public FruitAdapter(Context context, int resource, List<Fruit> objects) {
    super(context,resource, objects);
    // TODO Auto-generated constructor stub
    resourceId = resource;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
    Fruit fruit = getItem(position);
    View view = LayoutInflater.from(getContext()).inflate(resourceId, null);
    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());
    return view;
}

修改MainActivity:

private List<Fruit> fruitList = new ArrayList<Fruit>();
   @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);
       ListView listView = (ListView) findViewById(R.id.list_view);
       listView.setAdapter(adapter);
   }


   private void initFruits() {
    // TODO Auto-generated method stub
    Fruit apple = new Fruit("Apple", R.drawable.apple_pic);
    fruitList.add(apple);
    Fruit banana = new Fruit("Banana",R.drawable.banana_pic);
    fruitList.add(banana);
    Fruit orange = new Fruit("Orange", R.drawable.orange_pic);
    fruitList.add(orange);
    Fruit watermelon = new Fruit("Watermelon", R.drawable.watermelon_pic);
    fruitList.add(watermelon);
    Fruit pear = new Fruit("Pear",R.drawable.pear_pic);
    fruitList.add(pear);
    Fruit grape = new Fruit("Grape", R.drawable.grape_pic);
    fruitList.add(grape);
    Fruit pineapple = new Fruit("Pineapple",R.drawable.pineapple_pic);
    fruitList.add(pineapple);
    Fruit strawberry = new Fruit("Strawberry",R.drawable.strawberry_pic);
    fruitList.add(strawberry);
    Fruit cherry = new Fruit("Cherry", R.drawable.cherry_pic);
    fruitList.add(cherry);
    Fruit mango = new Fruit("Mango",R.drawable.mango_pic);
    fruitList.add(mango);
}

结果:
这里写图片描述

优化:
因为FruitAdapter里面的getView每次都加载了布局,效率不高,改成(加个判断):

Fruit fruit = getItem(position);

View view ;
if(convertView == null){
    view = LayoutInflater.from(getContext()).inflate(resourceId, null);
}else{
    view = convertView;

}
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());
return view;

进一步优化(不要每次都findViewById)

View view;
ViewHolder viewHolder;
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);
}else{
    view = convertView;
    viewHolder = (ViewHolder) view.getTag();

}
viewHolder.fruitImage.setImageResource(fruit.getImageId());
viewHolder.fruitName.setText(fruit.getName());
return view;

里面先要定义一个内部类:

class ViewHolder{
    ImageView fruitImage;
    TextView fruitName;
}

加上点击事件
Oncreate里面加上:

    listView.setOnItemClickListener(new OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
            long arg3) {
        // TODO Auto-generated method stub
        Fruit fruit = fruitList.get(arg2);
        Toast.makeText(MainActivity.this, fruit.getName(), Toast.LENGTH_SHORT).show();
    }
});

单位和尺寸

pt和px分别是磅数和像素,在不同的分辨率上显示会不一样,所以引入了dp(单位dai)和sp
获取当前dp:

getResources().getDisplayMetrics().xdpi

实践案例(聊天界面)

activity_main:

<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 something here"
       android:maxLines="2"
       />
   <Button 
       android:id="@+id/send"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Send"
       />
</LinearLayout>

新建msg_item.xml:

<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_left9"
        >
        <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_right9"
        >
        <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>

新建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;
    }
}

新建Adapter:

private int resourcedId;

public MsgAdapter(Context context, int textViewResourceId, List<Msg> objects) {
    super(context, textViewResourceId, objects);
    // TODO Auto-generated constructor stub
    resourcedId = textViewResourceId;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
    Msg msg = getItem(position);
    View view;
    ViewHolder viewHolder;
    if(convertView == null){
        view = LayoutInflater.from(getContext()).inflate(resourcedId, 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;

}

修改MainActivity:

private ListView msgListView;

private ListView msgListVeiw;
private EditText inputText;
private Button send;
private MsgAdapter adpter;

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();
       adpter = new MsgAdapter(MainActivity.this, R.layout.msg_item, msgList);
       inputText = (EditText) findViewById(R.id.input_text);
       send = (Button) findViewById(R.id.send);
       msgListVeiw = (ListView) findViewById(R.id.msg_list_view);
       msgListVeiw.setAdapter(adpter);
       send.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View arg0) {
            // TODO Auto-generated method stub
            String content = inputText.getText().toString();
            if(!"".equals(content)){
                Msg msg = new Msg(content,Msg.TYPE_SENT);
                msgList.add(msg);
                adpter.notifyDataSetChanged();
                msgListVeiw.setSelection(msgList.size());
                inputText.setText("");
            }
        }
    });
   }


   private void initMsgs() {
    // TODO Auto-generated method stub
    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 you", Msg.TYPE_RECEIVED );
    msgList.add(msg3);
}

结果:
控件使用draw9patch设定拉伸
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值