之前写过一个发帖界面,但是从来没有认真整理过,现在该写的写完了,好好整理下,不说废话,直接上效果图。(以下所有图片,全部来自百度贴吧客户端“借用”)
这个发帖界面主要实现功能包括,图片的上传,表情的实现。这篇我们先说表情功能的实现。
习惯性,从设计师那里拿到界面,先考虑布局,然后开始编写xml,如下面这个文件main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF">
<RelativeLayout
android:id="@+id/post_titlebar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentTop="true"
>
<TextView
android:id="@+id/post_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:layout_marginLeft="10dp"
android:textSize="16sp"
android:textColor="#FF00FF"
android:text="取消"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="#000000"
android:textSize="18sp"
android:text="发表帖子"/>
<TextView
android:id="@+id/post_submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:textSize="16sp"
android:textColor="#FF00FF"
android:text="发送"/>
</RelativeLayout>
<View
android:id="@+id/post_topLine"
android:layout_below="@id/post_titlebar"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#cdcdcd"/>
<EditText
android:id="@+id/post_inputEdit"
android:layout_below="@id/post_topLine"
android:layout_width="match_parent"
android:layout_height="100dp"
android:maxLines="5"
android:hint="说点什么吧"
android:textSize="14sp"
android:gravity="left|top"
android:cursorVisible="true"
android:background="@null"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_marginRight="10dp"
android:textColor="#959595"/>
<FrameLayout
android:id="@+id/post_imagePart"
android:layout_below="@id/post_inputEdit"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<ImageView
android:id="@+id/post_addPhoto"
android:layout_width="100dp"
android:layout_height="100dp"
android:scaleType="fitXY"
android:src="@drawable/add_photo"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"/>
<ImageView
android:id="@+id/post_deletePhoto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:src="@drawable/delete_photo"
android:layout_gravity="top|right"
android:visibility="invisible"/>
</FrameLayout>
<LinearLayout
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#cdcdcd"/>
<ImageView
android:id="@+id/post_addEmotion"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/add_emotion"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:layout_marginLeft="10dp"
android:scaleType="centerCrop"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#cdcdcd"/>
<FrameLayout
android:id="@+id/post_emotion_content"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_marginTop="5dp"
android:visibility="gone">
</FrameLayout>
</LinearLayout>
</RelativeLayout>
xml里面就这些东西,没什么好说的,只是这里我们的打算是,将表情界面当做一个Framgent来写。所以出现了一个id为post_emotion_content的FrameLayout,用来装载表情界面的Fragment。
xml编写完毕之后,接下来考虑我们的Fragment该如何编写,很明显表情界面整个是一个ViewPager,而在ViewPager的每个页面则是一个GridView,这样分析之下,整个界面的结构都出来了,编写代码轻而易举。
先看下emotion_main.xml的代码:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v4.view.ViewPager
android:id="@+id/emotion_viewPager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
/>
<LinearLayout
android:id="@+id/emotion_dotViewGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10dp"
android:orientation="horizontal"
android:layout_centerHorizontal="true">
</LinearLayout>
</RelativeLayout>
这个xml里就只包括我们需要的ViewPager和一个dotViewGroup。从表面意思也可以看出,dotViewGroup就是下方的点,看过
上一篇博客的话,大家应该对ViewPager的布局甚至adapter都非常熟悉了,这里不做具体介绍了。
接下来我们看整个Fragment的内容,为了方便,我们直接将很多类都写成了内部类。具体看下EmotionFragment.java文件,如下:
package com.example.postdemo;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.text.Selection;
import android.text.Spannable;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
/**
*
* @author happy_fsyy
*
*/
public class EmotionFragment extends Fragment implements OnItemClickListener {
/**
* 表情界面的布局
*/
private View emotionMain;
/**
* 装载表情页面的viewPager
*/
private ViewPager emotionViewpager;
/**
* 表情滑动下方的小点布局
*/
private LinearLayout dotViewGroup;
/**
* 每个页面其实是一个GridView
*/
private GridView[] emotionGridViews;
/**
* 定义页面数量
*/
private int pageCount;
/**
* 小点
*/
private View[] dots;
/**
* 表情图片
*/
private int[] emotionImgs;
/**
* 表情文字
*/
private String[] emotionText;
/**
* 当前 被选中页面index
*/
private int currentIndex;
private void initViews(){
emotionMain=getActivity().getLayoutInflater().inflate(R.layout.emotion_main, null);
emotionViewpager=(ViewPager)emotionMain.findViewById(R.id.emotion_viewPager);
dotViewGroup=(LinearLayout)emotionMain.findViewById(R.id.emotion_dotViewGroup);
}
/**
* 初始化viewPager
*/
private void initViewPager(){
emotionImgs=new int[]{
R.drawable.image_emoticon1,R.drawable.image_emoticon2,R.drawable.image_emoticon3,R.drawable.image_emoticon4,R.drawable.image_emoticon5
,R.drawable.image_emoticon6,R.drawable.image_emoticon7,R.drawable.image_emoticon8,R.drawable.image_emoticon9,R.drawable.image_emoticon10
,R.drawable.image_emoticon11,R.drawable.image_emoticon12,R.drawable.image_emoticon13,R.drawable.image_emoticon14,R.drawable.image_emoticon15
,R.drawable.image_emoticon16,R.drawable.image_emoticon17,R.drawable.image_emoticon18,R.drawable.image_emoticon19,R.drawable.image_emoticon20
,R.drawable.image_emoticon21,R.drawable.image_emoticon22,R.drawable.image_emoticon23,R.drawable.image_emoticon24,R.drawable.image_emoticon25
,R.drawable.image_emoticon26,R.drawable.image_emoticon27,R.drawable.image_emoticon28,R.drawable.image_emoticon29,R.drawable.image_emoticon30
,R.drawable.image_emoticon31,R.drawable.image_emoticon32,R.drawable.image_emoticon33
};
//这里的字符串可以任意更换
emotionText=getActivity().getResources().getStringArray(R.array.emotion_texts);
currentIndex=0;
pageCount=emotionImgs.length/15+1;//每个页面15个表情
emotionGridViews=new GridView[pageCount];
dots=new View[pageCount];
int i=0;
//初始化每个页面的gridview
for(i=0;i<pageCount;i++){
emotionGridViews[i]=new GridView(getActivity());
emotionGridViews[i].setStretchMode(GridView.STRETCH_COLUMN_WIDTH);
emotionGridViews[i].setNumColumns(5);
emotionGridViews[i].setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT));
emotionGridViews[i].setGravity(Gravity.CENTER);
emotionGridViews[i].setAdapter(new GridViewAdapter(getActivity(), i));
emotionGridViews[i].setOnItemClickListener(this);
}
for(i=0;i<pageCount;i++){
dots[i]=new View(getActivity());
LinearLayout.LayoutParams lp=new LinearLayout.LayoutParams(10, 10);
lp.setMargins(10, 0, 10, 0);
dots[i].setLayoutParams(lp);
if(i!=currentIndex){
dots[i].setBackgroundResource(R.drawable.dot_normal);
}else{
dots[i].setBackgroundResource(R.drawable.dot_focused);
}
dotViewGroup.addView(dots[i]);
}
emotionViewpager.setAdapter(new EmotionPagerAdapter());
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initViews();
initViewPager();
emotionViewpager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
currentIndex=position;
for(int i=0;i<pageCount;i++){
if(i==currentIndex){
dots[i].setBackgroundResource(R.drawable.dot_focused);
}else{
dots[i].setBackgroundResource(R.drawable.dot_normal);
}
}
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return emotionMain;
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
EditText inputEditText=(EditText)getActivity().findViewById(R.id.post_inputEdit);
EmotionParser parser=new EmotionParser(getActivity());
String content=inputEditText.getText().append(emotionText[currentIndex*15+position]).toString();
inputEditText.setText(parser.replace(content));
Spannable text=(Spannable)inputEditText.getText();
Selection.setSelection(text, text.length());
}
private class GridViewAdapter extends BaseAdapter{
private Context context;//Context
private int pageIndex;//页面索引
/**
* @param context Context
* @param pageIndex 第几页
*/
public GridViewAdapter(Context context,int pageIndex) {
this.context=context;
this.pageIndex=pageIndex;
}
@Override
public int getCount() {
if(pageIndex<pageCount-1){
return 15;
}else{
return emotionImgs.length%15;
}
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView view;
if(convertView==null){
view=new ImageView(context);
view.setLayoutParams(new GridView.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
view.setScaleType(ImageView.ScaleType.CENTER_CROP);
view.setPadding(8, 8, 8, 8);
}else{
view=(ImageView)convertView;
}
view.setImageResource(emotionImgs[pageIndex*15+position]);
return view;
}
}
private class EmotionPagerAdapter extends PagerAdapter{
@Override
public int getCount() {
return pageCount;
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0==arg1;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(emotionGridViews[position]);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
((ViewPager)container).addView(emotionGridViews[position]);
return emotionGridViews[position];
}
}
}
根据代码注释看起来应该没有任何问题了,具体的代码下载请看下一篇。