仿微信公众号界面实现
来源:互联网 发布:opencv读取caffe 编辑:程序博客网 时间:2024/05/16 18:33
最近在做一个关于微信公众平台服务号的小项目,主要用来实现排队叫号功能。一直都对微信公众号开发比较好奇,于是趁这次机会仔细研究了一下公众号的开发流程和逻辑架构。
微信公众平台现在分为3类:订阅号,服务号和企业号。其中,服务号和企业号的开放权限比较高,可以实现自定义菜单功能,调用摄像头以及LBS等API。
基本通信架构如图:
在项目的功能设计阶段本想搭建一个服务号Demo用来展示,但微信服务号的认证手续太麻烦,而且我也没有那个资质去开通服务号。于是打算自己做一个仿微信公众号的基本界面,先实现菜单功能,避免开发初期的公众号注册,同时也方便展示。
先上效果图:
1. 界面布局
主界面布局四部分,由上到下依次是:标题栏,消息列表,底部菜弹出的子菜单,底部菜单或输入栏。
主界面基本框架main.xml代码如下:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/main" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#E4E4E4" > <!-- 消息列表 --> <ListView android:id="@+id/lv" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginBottom="50dp" android:layout_marginTop="10dp" android:cacheColorHint="#00000000" android:divider="#00000000" android:dividerHeight="20dp" android:scrollbars="none" > </ListView> <!-- 点击底部菜单后弹出的子菜单 --> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:layout_marginBottom="50dp" android:orientation="horizontal" > <View android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="0.5" /> <LinearLayout android:id="@+id/pop_layout1" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="bottom" android:layout_weight="1" android:orientation="vertical" > </LinearLayout> <LinearLayout android:id="@+id/pop_layout2" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="bottom" android:layout_weight="1" android:orientation="vertical" > </LinearLayout> <LinearLayout android:id="@+id/pop_layout3" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="bottom" android:layout_weight="1" android:orientation="vertical" > </LinearLayout> </LinearLayout> <!-- 底部菜单 --> <LinearLayout android:id="@+id/bottom_layout" android:layout_width="fill_parent" android:layout_height="50dp" android:layout_gravity="bottom" android:background="#00ffffff" android:orientation="vertical" > <LinearLayout android:id="@+id/bottom_menu_layout1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff" android:orientation="vertical" > <View android:layout_width="fill_parent" android:layout_height="1px" android:background="#A6A6A6" /> <LinearLayout android:id="@+id/menu_layout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center" android:orientation="horizontal" > <ImageView android:id="@+id/keyboard" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:layout_marginLeft="3dp" android:layout_marginRight="3dp" android:layout_marginTop="5dp" android:layout_weight="0.5" android:background="@drawable/keyboard" /> <View android:layout_width="1px" android:layout_height="fill_parent" android:background="#A6A6A6" /> <RelativeLayout android:id="@+id/btn1" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@drawable/btn_selector" > <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_margin="5dp" > <TextView android:id="@+id/text1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_centerInParent="true" android:gravity="center" android:text="用户绑定" android:textColor="#000000" android:textSize="16sp" /> <ImageView android:layout_width="10dp" android:layout_height="10dp" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:src="@drawable/more_icon" android:visibility="invisible" /> </RelativeLayout> </RelativeLayout> <View android:layout_width="1px" android:layout_height="fill_parent" android:background="#A6A6A6" /> <RelativeLayout android:id="@+id/btn2" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@drawable/btn_selector" > <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_margin="5dp" > <TextView android:id="@+id/text2" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_centerInParent="true" android:gravity="center" android:text="扫描签到" android:textColor="#000000" android:textSize="16sp" /> <ImageView android:layout_width="10dp" android:layout_height="10dp" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:src="@drawable/more_icon" android:visibility="invisible" /> </RelativeLayout> </RelativeLayout> <View android:layout_width="1px" android:layout_height="fill_parent" android:background="#A6A6A6" /> <RelativeLayout android:id="@+id/btn3" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" android:background="@drawable/btn_selector" > <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_margin="5dp" > <TextView android:id="@+id/text3" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_centerInParent="true" android:gravity="center" android:text="更多" android:textColor="#000000" android:textSize="16sp" /> <ImageView android:layout_width="10dp" android:layout_height="10dp" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:src="@drawable/more_icon" android:visibility="visible" /> </RelativeLayout> </RelativeLayout> </LinearLayout> </LinearLayout> </LinearLayout></FrameLayout>
标题栏title_bar.xml布局如下:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" > <!-- 返回 --> <ImageView android:id="@+id/title_bar_back_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:layout_marginLeft="10dip" android:src="@drawable/back" /> <!-- 服务号名称 --> <TextView android:id="@+id/my_setting_title_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="腾讯招聘面试服务" android:textColor="#ffffff" android:textSize="20sp" /> <!-- 服务号 --> <ImageView android:id="@+id/title_bar_my" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="10dip" android:src="@drawable/my" /></RelativeLayout>
完成title_bar布局后,再在values\styles.xml添加自定义标题栏主题
<!-- 自定义标题栏背景颜色 --> <style name="CustomWindowTitleBackground"> <item name="android:background">#32394A</item> </style> <!-- 自定义标题栏主题 --> <style name="myTheme" parent="android:Theme"> <item name="android:windowTitleSize">45dp</item> <item name="android:windowTitleBackgroundStyle">@style/CustomWindowTitleBackground</item> </style>消息列表的服务端消息item布局item_left.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="horizontal" > <RelativeLayout android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="4" > <ImageView android:id="@+id/server_image" android:layout_width="40dp" android:layout_height="40dp" android:layout_marginLeft="2dp" android:background="@drawable/qq"/> <TextView android:id="@+id/server_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="2dp" android:layout_toRightOf="@id/server_image" android:background="@drawable/text_bg_left1" android:gravity="center_vertical|left" android:textSize="16sp" android:textColor="#000000"/> </RelativeLayout> <View android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" /></LinearLayout>消息列表的用户消息item布局item_right.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="horizontal" > <View android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="1" /> <RelativeLayout android:layout_width="0dp" android:layout_height="fill_parent" android:layout_weight="4" > <ImageView android:id="@+id/user_image" android:layout_width="40dp" android:layout_height="40dp" android:layout_alignParentRight="true" android:layout_marginRight="2dp" android:background="@drawable/qq" /> <TextView android:id="@+id/user_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="1dp" android:layout_toLeftOf="@id/user_image" android:background="@drawable/text_bg_right1" android:gravity="center_vertical|right" android:textColor="#000000" android:textSize="16sp" /> </RelativeLayout></LinearLayout>弹出的子菜单布局child_menu.xml如下:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/child_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#FFFFFF" android:gravity="bottom" android:orientation="vertical" > <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" > <Button android:id="@+id/test1" android:layout_width="wrap_content" android:layout_height="45dp" android:background="@drawable/btn_selector" android:paddingLeft="10dp" android:paddingRight="10dp" android:text="进度查询" android:textColor="#000000" android:textSize="16sp" /> <View android:layout_width="wrap_content" android:layout_height="1px" android:layout_alignLeft="@id/test1" android:layout_alignRight="@id/test1" android:layout_below="@id/test1" android:background="#E4E4E4" /> </RelativeLayout> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" > <Button android:id="@+id/test1" android:layout_width="wrap_content" android:layout_height="45dp" android:background="@drawable/btn_selector" android:paddingLeft="10dp" android:paddingRight="10dp" android:text="使用帮助" android:textColor="#000000" android:textSize="16sp" /> <View android:layout_width="wrap_content" android:layout_height="1px" android:layout_alignLeft="@id/test1" android:layout_alignRight="@id/test1" android:layout_below="@id/test1" android:background="#E4E4E4" /> </RelativeLayout> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" > <Button android:id="@+id/test1" android:layout_width="wrap_content" android:layout_height="45dp" android:background="@drawable/btn_selector" android:paddingLeft="10dp" android:paddingRight="10dp" android:text="联系我们" android:textColor="#000000" android:textSize="16sp" /> <View android:layout_width="wrap_content" android:layout_height="1px" android:layout_alignLeft="@id/test1" android:layout_alignRight="@id/test1" android:layout_below="@id/test1" android:background="#E4E4E4" /> </RelativeLayout></LinearLayout>
由底部菜单切换到输入框,输入框bottom_menu_layout2.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" > <LinearLayout android:id="@+id/bottom_menu_layout2" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff" android:orientation="vertical" > <View android:layout_width="fill_parent" android:layout_height="1px" android:background="#A6A6A6" /> <LinearLayout android:id="@+id/menu_layout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center" android:orientation="horizontal" > <!-- 左侧切换菜单按钮 --> <ImageView android:id="@+id/menu" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:layout_marginLeft="3dp" android:layout_marginRight="3dp" android:layout_marginTop="5dp" android:layout_weight="0.5" android:background="@drawable/menu" /> <View android:layout_width="1px" android:layout_height="fill_parent" android:background="#A6A6A6" /> <RelativeLayout android:id="@+id/btn1" android:layout_width="0dp" android:layout_height="fill_parent" android:layout_margin="5dp" android:layout_weight="3" android:background="#ffffff" > <ImageView android:id="@+id/voice" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_centerInParent="true" android:layout_marginLeft="5dp" android:src="@drawable/voice" /> <!-- 右侧“+”按钮或发送按钮 --> <Button android:id="@+id/add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerInParent="true" android:layout_marginRight="1dp" android:background="@drawable/add" android:paddingBottom="5dp" android:paddingLeft="8dp" android:paddingRight="8dp" android:paddingTop="5dp" android:text="" android:textColor="#ffffff" android:textSize="14sp" /> <!-- 输入 --> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_toLeftOf="@id/add" android:layout_toRightOf="@id/voice" > <EditText android:id="@+id/input_text" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:background="#00000000" android:gravity="bottom" android:paddingLeft="2dp" android:paddingRight="2dp" android:text="" android:textColor="#000000" android:textSize="16sp" /> <View android:layout_width="fill_parent" android:layout_height="1px" android:layout_below="@id/input_text" android:layout_marginTop="10dp" android:background="#A6A6A6" /> </RelativeLayout> </RelativeLayout> </LinearLayout> </LinearLayout></LinearLayout>
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<Map<String, String>> listData = new ArrayList<Map<String, String>>();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;@Overrideprotected 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);}@Overridepublic void onClick(View v) {// TODO Auto-generated method stubint 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<String, String> map = new HashMap<String, String>();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() {@Overridepublic void onFocusChange(View v, boolean hasFocus) {// TODO Auto-generated method stubif (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<String, String> map;map = new HashMap<String, String>();map.put("type", "1");// 消息类型,服务端为0,用户为1map.put("text", text);listData.add(map);map = new HashMap<String, String>();map.put("type", "0");map.put("text", "帐号已绑定成功,请您准时签到。");listData.add(map);adapter.notifyDataSetChanged();bind = true;}}private class MyAdapter extends BaseAdapter {public List<Map<String, String>> list;private Context context;private int type;private ListView listView;public MyAdapter(Context context, List<Map<String, String>> list) {this.context = context;this.list = list;}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn list.size();}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn list.get(position);}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// TODO Auto-generated method stubViewHolder viewHolder = null;Map<String, String> map = (Map<String, String>) 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个。
0 0
- 仿微信公众号界面实现
- Android开发学习之微信公众号界面
- android跳转微信指定公众号界面
- Android开发学习之微信公众号界面
- bootstrap开发微信公众号后台界面
- 微信公众号开发(三)前端界面
- 微信公众号开发实现原理
- 微信公众号下载文件实现
- zabbix实现微信公众号告警
- thinkphp3.2 实现接入公众号
- 微信公众号授权认证实现
- php实现微信公众号授权
- 微信公众号实现会员卡领取
- 微信公众号实现机器人回复
- android仿微信界面的实现
- 仿微信6.0主界面实现
- 设计实现微信公众号新增素材页面,用于添加公众号临时,永久素材
- php开发实现关注公众号事件推送,公众号关注推送图文
- Java中throw和throws的区别
- STL系列之十 全排列(百度迅雷笔试题)
- Java中向上转型
- [Win32]键盘接口简介
- android呼叫流程源码分析
- 仿微信公众号界面实现
- leetcode Valid Parentheses
- 10.12-10.25
- 一致性hash算法理解
- Protocol 保护,私有,公有
- 双系统为linux扩容
- 第五天CCTouch详解
- jetty之嵌入式运行jetty
- PHP中静态(static)调用非静态方法详解