android表情功能开发

之前写过一个发帖界面,但是从来没有认真整理过,现在该写的写完了,好好整理下,不说废话,直接上效果图。(以下所有图片,全部来自百度贴吧客户端“借用”)



这个发帖界面主要实现功能包括,图片的上传,表情的实现。这篇我们先说表情功能的实现。

习惯性,从设计师那里拿到界面,先考虑布局,然后开始编写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];
		}
	}

}

根据代码注释看起来应该没有任何问题了,具体的代码下载请看下一篇。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值