仿微信公众号界面实现

最近在做一个关于微信公众平台服务号的小项目,主要用来实现排队叫号功能。一直都对微信公众号开发比较好奇,于是趁这次机会仔细研究了一下公众号的开发流程和逻辑架构。

微信公众平台现在分为3类:订阅号,服务号和企业号。其中,服务号和企业号的开放权限比较高,可以实现自定义菜单功能,调用摄像头以及LBS等API。

基本通信架构如图:

仿微信公众号界面实现_第1张图片

在项目的功能设计阶段本想搭建一个服务号Demo用来展示,但微信服务号的认证手续太麻烦,而且我也没有那个资质去开通服务号。于是打算自己做一个仿微信公众号的基本界面,先实现菜单功能,避免开发初期的公众号注册,同时也方便展示。

先上效果图:

仿微信公众号界面实现_第2张图片 仿微信公众号界面实现_第3张图片 仿微信公众号界面实现_第4张图片


1. 界面布局

主界面布局四部分,由上到下依次是:标题栏,消息列表,底部菜弹出的子菜单,底部菜单或输入栏。

主界面基本框架main.xml代码如下:



    

    
    

    

    

        

        
        

        
        

        
        
    
    
    

    

        

            

            

                

                

                

                    

                        

                        
                    
                

                

                

                    

                        

                        
                    
                

                

                

                    

                        

                        
                    
                
            
        
    

标题栏title_bar.xml布局如下:




    

    
    
    

    
    
    

    

完成title_bar布局后,再在values\styles.xml添加自定义标题栏主题


    

    
    
消息列表的服务端消息item布局item_left.xml




    
        
        
    

    

消息列表的用户消息item布局item_right.xml



    

    

        

        
    

弹出的子菜单布局child_menu.xml如下:




    

        

由底部菜单切换到输入框,输入框bottom_menu_layout2.xml布局如下:




    

        

        

            

            

            

            

                


                

                

2. 代码实现

MainActivity.java

package com.example.wxdemo;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class MainActivity extends Activity implements View.OnClickListener {

	private LinearLayout bottomLayout;// 底部菜单父框架
	private LinearLayout bottomMenuLayout1;// 底部菜单布局
	private LinearLayout bottomMenuLayout2;// 底部输入框布局
	private RelativeLayout btn1;// “用户绑定”按钮布局
	private RelativeLayout btn2;// “扫描签到”按钮布局
	private RelativeLayout btn3;// “更多”按钮布局
	private LinearLayout popLayout1;
	private LinearLayout popLayout2;
	private LinearLayout popLayout3;// 弹出的子菜单父框架布局
	private LinearLayout childLayout;// “更多”按钮的子菜单
	private ListView lv;
	private MyAdapter adapter;
	private List> listData = new ArrayList>();

	private ImageView keyboard;// 底部键盘切换图标
	private ImageView menu;// 底部菜单切换图标
	private Button send;// 发送按钮
	private EditText inputText;// 输入框

	private boolean open = true;// 子菜单填充状态标记
	private boolean flag = false;// 子菜单显示状态标记
	private boolean bind = false;// 用户绑定状态标记

	private Animation animEnter;// 底部菜单进入动画
	private Animation animExit;// 底部菜单退出动画

	private View view;
	private View view2;
	private LayoutInflater inflater;

	private int myID = 0;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		this.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
		setContentView(R.layout.main);
		getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
				R.layout.title_bar);// 自定义标题栏

		inflater = MainActivity.this.getLayoutInflater();

		popLayout1 = (LinearLayout) findViewById(R.id.pop_layout1);
		popLayout2 = (LinearLayout) findViewById(R.id.pop_layout2);
		popLayout3 = (LinearLayout) findViewById(R.id.pop_layout3);

		bottomLayout = (LinearLayout) findViewById(R.id.bottom_layout);
		bottomMenuLayout1 = (LinearLayout) findViewById(R.id.bottom_menu_layout1);

		keyboard = (ImageView) findViewById(R.id.keyboard);
		btn1 = (RelativeLayout) findViewById(R.id.btn1);
		btn2 = (RelativeLayout) findViewById(R.id.btn2);
		btn3 = (RelativeLayout) findViewById(R.id.btn3);

		lv = (ListView) findViewById(R.id.lv);

		btn1.setOnClickListener(this);
		btn2.setOnClickListener(this);
		btn3.setOnClickListener(this);
		keyboard.setOnClickListener(this);

		adapter = new MyAdapter(this, listData);
		lv.setAdapter(adapter);

	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		int id = v.getId();
		switch (id) {
		case R.id.btn1:
			btn1Click();
			break;
		case R.id.btn2:
			break;
		case R.id.btn3:
			btn3Click();
			break;
		case R.id.keyboard:
			keyboardClick();
			break;
		case R.id.menu:
			menuClick();
			break;
		case R.id.add:
			sendClick();
			break;
		default:
			break;
		}
	}

	public void btn1Click() {// 用户绑定
		Map map = new HashMap();
		map.put("type", "0");
		if (!bind) {
			map.put("text", "请输入您的手机号或简历ID进行帐号绑定,绑定成功后才能进行签到。");
		} else {
			map.put("text", "帐号已绑定成功,请您准时签到。");
		}
		listData.add(map);
		adapter.notifyDataSetChanged();
	}

	public void btn2Click() {// 扫描签到
		// TODO
	}

	public void btn3Click() {// 更多
		if (open == true) {
			view = inflater.inflate(R.layout.child_menu, popLayout3, true);
			childLayout = (LinearLayout) view.findViewById(R.id.child_layout);
			open = false;
		}

		if (flag == false) {
			flag = true;
			childLayout.setVisibility(View.VISIBLE);
		} else {
			flag = false;
			childLayout.setVisibility(View.GONE);
		}
	}

	public void keyboardClick() {//点击键盘按钮,由底部菜单切换为底部输入
		view2 = inflater.inflate(R.layout.bottom_menu_layout2, bottomLayout,
				true);
		bottomMenuLayout2 = (LinearLayout) view2
				.findViewById(R.id.bottom_menu_layout2);
		animEnter = AnimationUtils.loadAnimation(MainActivity.this,
				R.anim.my_pop_enter_anim);
		animExit = AnimationUtils.loadAnimation(MainActivity.this,
				R.anim.my_pop_exit_anim);
		animEnter.setStartOffset(200);
		bottomMenuLayout1.startAnimation(animExit);
		bottomMenuLayout1.setVisibility(View.GONE);
		bottomMenuLayout2.startAnimation(animEnter);
		bottomMenuLayout2.setVisibility(View.VISIBLE);
		menu = (ImageView) view2.findViewById(R.id.menu);
		inputText = (EditText) view2.findViewById(R.id.input_text);
		send = (Button) view2.findViewById(R.id.add);
		menu.setOnClickListener(this);
		send.setOnClickListener(this);
		inputClick();
	}

	public void menuClick() {//点击菜单按钮,由底部输入框切换为底部菜单
		bottomMenuLayout2.startAnimation(animExit);
		bottomMenuLayout2.setVisibility(View.GONE);
		bottomMenuLayout1.startAnimation(animEnter);
		bottomMenuLayout1.setVisibility(View.VISIBLE);
	}

	public void inputClick() {
		inputText.setOnFocusChangeListener(new OnFocusChangeListener() {

			@Override
			public void onFocusChange(View v, boolean hasFocus) {
				// TODO Auto-generated method stub
				if (hasFocus) {
					send.setBackgroundResource(R.drawable.send_btn_bg);
					send.setText("发送");
				} else {
					send.setBackgroundResource(R.drawable.add);
					send.setText("  ");
				}
			}
		});
	}

	public void sendClick() {
		String text = inputText.getEditableText().toString();
		inputText.setText("");
		if (text != null && (!text.equals(""))) {
			Map map;
			map = new HashMap();
			map.put("type", "1");// 消息类型,服务端为0,用户为1
			map.put("text", text);
			listData.add(map);

			map = new HashMap();
			map.put("type", "0");
			map.put("text", "帐号已绑定成功,请您准时签到。");
			listData.add(map);
			adapter.notifyDataSetChanged();
			bind = true;
		}
	}

	private class MyAdapter extends BaseAdapter {
		public List> list;
		private Context context;
		private int type;
		private ListView listView;

		public MyAdapter(Context context, List> list) {
			this.context = context;
			this.list = list;
		}

		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return list.size();
		}

		@Override
		public Object getItem(int position) {
			// TODO Auto-generated method stub
			return list.get(position);
		}

		@Override
		public long getItemId(int position) {
			// TODO Auto-generated method stub
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			// TODO Auto-generated method stub
			ViewHolder viewHolder = null;
			Map map = (Map) list.get(position);
			if (map.get("type").equals("0")) {// 服务端
				if (convertView == null) {
					convertView = inflater.inflate(R.layout.item_left, parent,
							false);
					viewHolder = new ViewHolder();
					viewHolder.mTextView = (TextView) convertView
							.findViewById(R.id.server_text);
					viewHolder.mImageView = (ImageView) convertView
							.findViewById(R.id.server_image);
					convertView.setTag(viewHolder);
				} else {
					viewHolder = (ViewHolder) convertView.getTag();
				}

				viewHolder.mTextView.setText(map.get("text"));

			} else {// 用户
				if (convertView == null) {
					convertView = inflater.inflate(R.layout.item_right, parent,
							false);
					viewHolder = new ViewHolder();
					viewHolder.mTextView = (TextView) convertView
							.findViewById(R.id.user_text);
					viewHolder.mImageView = (ImageView) convertView
							.findViewById(R.id.user_image);
					convertView.setTag(viewHolder);
				} else {
					viewHolder = (ViewHolder) convertView.getTag();
				}
				viewHolder.mTextView.setText(map.get("text"));
			}

			return convertView;
		}

	}

	private final class ViewHolder {
		TextView mTextView;
		ImageView mImageView;
	}

}

以上就是实现仿微信服务号的主要代码,菜单功能并没用完全实现,可根据实际情况和需要进行添加。同时还需注意的是,底部菜单最多为3个,每个名称限制在7个字符,包含的子菜单最多只能有5个。




你可能感兴趣的:(Android)