您的位置:首页 > 其它

Nine-Patch点九切图法

2016-05-12 22:31 465 查看
制作Nine-Patch图片

这是一种被特殊处理过的png图片,能够指定哪些区域可以被拉伸而哪些区域不可以

比如有这样一张图



<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.uibestpractice.MainActivity" >

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

</RelativeLayout>


它就变成了这样



可以看到,由于图片的宽高不足以填满整个屏幕的宽度,整张图片被均匀地拉伸了,这种效果非常差

这时我们就可以使用Nine-Patch图片来进行改善

在Android sdk目录下有一个tools文件夹,在这个文件夹中找到draw9patch.bat文件,我们就是使用它来制作Nine-Patch图片的

使用点九图片的效果



编写一个简易的聊天界面

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#d8e0e8"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.uibestpractice.MainActivity" >

<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>

</LinearLayout>


这里在主界面中放置了一个ListView用于显示聊天的消息内容,又放置了一个EditText用于输入消息,还放置了一个Button用于发送消息

ListView用到了一个android:divider属性,它可以指定ListView分割线的颜色,这里#0000表示将分割线设为透明色

然后我们来定义一个消息的实体类

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

}


Msg类中只有两个字段,content表示消息的内容,type表示消息的类型

其中消息类型有两个值可选,TYPE_RECEIVED表示这是一条收到的消息,TYPE_SENT表示这是一条发出的消息

接着来编写ListView子项的布局

新建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/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/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>


这里我们让收到的消息居左对齐,发出的消息居右对齐

怎样才能让收到的消息和发出的消息都放在同一个布局里呢?

只要根据消息的类型来决定隐藏和显示哪种消息就可以了

接下来需要创建ListView的适配器类,让它继承自ArrayAdapter,并将泛型指定为Msg类

新建MsgAdapter

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

}


getView()方法中增加了对消息类型的判断

如果这条消息是收到的,则显示左边的消息布局,如果这条消息是发出的,则显示右边的消息布局

最后修改MainActivity中的代码,来为ListView初始化一些数据,并给发送按钮加入事件响应

public class MainActivity extends Activity {

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);
initMsg(); // 初始化消息数据
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(); // 当有新消息时,刷新ListView中的显示
msgListView.setSelection(msgList.size()); // 将ListView定位到最后一行
inputText.setText(""); // 清空输入框的内容
}
}
});
}

private void initMsg() {
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);
}
}


在initMsgs()方法中我们先初始化了几条数据用于在ListView中显示

然后在发送按钮的点击事件里获取了EditText中的内容

如果内容不为空则创建出一个新的Msg对象,并把它添加到msgList列表中去

之后又调用了适配器的notifyDataSetChanged()方法,用于通知列表的数据发生了变化,这样新增的一条消息才能够在ListView中显示

接着调用ListView的setSelection()方法将显示的数据定位到最后一行,以保证一定可以看得到最后发出的一条消息

最后调用EditText的setText()方法将输入的内容清空



源码及图片资源地址https://github.com/LiuchangDuan/uibestpractice
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: