码迷,mamicode.com
首页 > 其他好文 > 详细

J哥---------公司(视频 社交)项目分享

时间:2015-07-07 13:02:23      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:视频   社交应用   openfire   asmack   聊天室   

最近公司工作比较轻松,就把以前的项目 拿来整理下。以前公司做视频社交这一块,类似于YY直播。

展示

先来个动态图

技术分享

再简单看一下主要界面

首页第一个界面,这里可以看美女,看直播
技术分享
这是任务列界面,可以领取每日任务,任务分成长 和推荐
技术分享
好友列表
技术分享
用户的个人中心页
技术分享
直播间
技术分享
用户的个人中心页
技术分享
充值方式页
技术分享
银联支付页
技术分享

项目组成

这个项目主要的重点就两个地方,看视频,和 与主播互动。
整个视频流是用RTMP协议的,文字聊天走的是openfire+asmack .
PS:整个项目,我们产品设计的很不错的,只是我水平有限,有些功能 实现不了!
再介绍下,整个项目都用到了什么?
程序框架:SlidingMenu+Viewpager+fragment
请求服务器: asynchttpclient
解析数据:Gson
消息推送: Jpush
页面数据分析: Umeng
充值方式: alipay +银联+yeepay+短信充值
图片缓存: afinal
自定义view: Pulltoresfresh+拼音排序联系人+horizontallistview+verticalviewpager…
技术分享

另,我把公司的项目写出来,是因为公司的服务器停掉了,所以,一些数据,是我自己抓出其他应用里面的(抓取数据的方法,在上面一篇文章里)….
首先就是整个项目最下面是mainactivity,这个大家是都有共识的,在mainactivity 上面 我们就要 引入slidingmenu,
关于slidingmenu的下载,就不介绍了,这里直接拿来用
包结构比较清晰
技术分享
整个项目首先,由splashactivity 欢迎界面 ,进行检查,然后跳转到mainactivity,mainactivity 中包含slidingmenu,slidingmenu的中间界面 添加了viewpager,viewpager 里面添加了四个fragment。

由于默认v4包里的viewpager 会默认混存数据,即使你设置了setOffscreenPageLimit(0),所以这里替换掉原生的v4包,并且通过fragment 的 setuservisibilityhint 方法来,控制 fragment 界面的动态刷新。

主界面的第一个fragment ,也就是约美女的界面,通过fragmenttabhost,来实现约美女,和看直播的切换。
在约美女中,就是一个简单地pulltorefreshlistview,适配了一个item.点击item 进入用户的个人中心, 个人中心 顶部 是个人的宣传适配,下面,是用户自己上传的 公开专辑,或者私密专辑。可以点赞,关注他。

做任务界面是有两种任务,一种是 每日任务,就是 登陆,签到,另一种是下载app 得积分任务。 下载app 可以控制 下载 暂停。

在我的关注界面。是你关注的好友,这个跟微信的联系人控件是一样的。首字母排序,用到了比较器。
首先 把汉字,对应首字母提取出来,然后与A-Z 排序。以及特殊字符~。

基本代码

整个项目 基本框架 简单描述下
在MainActiviy中初始化 slidingmenu。MainActivity 布局文件

<?xml version="1.0" encoding="utf-8"?>
<com.os.slidingmenu.SlidingMenu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:sliding="http://schemas.android.com/apk/res-auto"
android:id="@+id/slidingmenu"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
sliding:behindOffset="60dp"
sliding:fadeEnabled="true"
sliding:mode="left"
sliding:secondaryShadowDrawable="@drawable/sliding_shadow_right"
sliding:shadowDrawable="@drawable/sliding_shadow_left"
sliding:shadowWidth="10dp"
sliding:touchModeAbove="fullscreen"
sliding:touchModeBehind="margin" />

MainActivity这个类进行初始化。

package com.os.activity;
import java.lang.ref.WeakReference;
import com.os.activity.base.BaseFragmentActivity;
import com.os.activity.base.BaseSlidingFragment;
import com.os.activity.sliding.LeftFragment;
import com.os.activity.sliding.RightFragment;
import com.os.slidingmenu.R;
import com.os.slidingmenu.SlidingMenu;
import com.os.ui.MainHallFragment;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;


public class MainActivity extends BaseFragmentActivity {
    private Fragment mCurFragment;
    public static SlidingMenu mSlidingMenu;
    private Handler handler = new MyHandler(this);
    private static class MyHandler extends Handler {
        private final WeakReference<MainActivity> mActivity;

        public MyHandler(MainActivity activity) {
            mActivity = new WeakReference<MainActivity>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            MainActivity activity = mActivity.get();
            if (activity == null) {
                return;
            }
            activity.handleMsg(msg);
        }
    }

    private void handleMsg(Message msg) {

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initViews();


        if (savedInstanceState != null) {
            mCurFragment = getSupportFragmentManager().getFragment(savedInstanceState, "mCurContent");
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        getSupportFragmentManager().putFragment(outState, "mCurContent", mCurFragment);
    }
    private void initViews() {// 通过id 找到slidingmenu 
        mSlidingMenu = (SlidingMenu) findViewById(R.id.slidingmenu);
        mSlidingMenu.setMenu(R.layout.sliding_left_frame);//给slidingmenu 添加左边的布局

        if (getFragmentByTag(LeftFragment.class) == null) {//添加左边fragment
            getSupportFragmentManager().beginTransaction().add(R.id.left_frame, new LeftFragment(), LeftFragment.class.getName()).commit();
        }

        mSlidingMenu.setContent(R.layout.sliding_center_frame);//添加一个空布局,后面承载 中间的fragment

        mSlidingMenu.setSecondaryMenu(R.layout.sliding_right_frame);//添加右面的布局,添加右边的fragment
        if (getFragmentByTag(RightFragment.class) == null) {
            getSupportFragmentManager().beginTransaction().add(R.id.right_frame, new RightFragment(), RightFragment.class.getName()).commit();
        }

        if (mCurFragment != null) {
            postSwitchFragment();
        }
        mSlidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN);//设置滑动模式,边缘  还是整个界面
    }
    /**
     * slidingMenu中的内容Fragment切换(左侧菜单触发)
     * 
     * @param clazz
     */
    public void switchCenterFragment(Class<? extends Fragment> clazz) {
        try {
            if (mSlidingMenu == null) {
                removeAllFragments();
                return;
            }
            boolean isInit = false;
            FragmentManager fm = getSupportFragmentManager();
            FragmentTransaction ft = fm.beginTransaction();
            Fragment userFragment = fm.findFragmentByTag(clazz.getName());
            if (userFragment == null) {
                isInit = true;
                try {
                    userFragment = clazz.newInstance();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            if (mCurFragment != null && mCurFragment != userFragment) {
                ft.hide(mCurFragment);
            }

            if (!userFragment.isAdded() && isInit) {
                ft.add(R.id.center_frame, userFragment, clazz.getName());
            } else {
                ft.show(userFragment);
            }

            ft.commitAllowingStateLoss();

            mCurFragment = userFragment;

            if (MainHallFragment.class.getName().equals(clazz.getName())) {
                mSlidingMenu.setMode(SlidingMenu.LEFT_RIGHT);
                if (!isInit) {
                    ((MainHallFragment) userFragment).postScrollTop();

                }

            } else {

                mSlidingMenu.setMode(SlidingMenu.LEFT_RIGHT);

            }

            postShowContent(200);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * lidingMenu中的内容Fragment内容过滤(右侧菜单触发)
     * 
     * @param clazz
     * @param type
     */
    public void filterCenterFragment(Class<? extends BaseSlidingFragment> clazz, int type) {
        BaseSlidingFragment userFragment = (BaseSlidingFragment) getFragmentByTag(clazz);
        if (userFragment != null) {
            userFragment.filter(type);
        }
        if (mSlidingMenu != null)
            mSlidingMenu.showContent();
    }
    /**
     * 延迟切换Fragment
     */
    private void postSwitchFragment() {
        handler.postDelayed(new Runnable() {

            @Override
            public void run() {
                switchCenterFragment(mCurFragment.getClass());
            }
        }, 50);

    }

    /**
     * 清除FragmentManager中所有Fragment
     */
    private void removeAllFragments() {
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        for (int i = 0; i < LeftFragment.FRAGMENTS_CLASSES.length; i++) {
            Fragment fragment = getFragmentByTag(LeftFragment.FRAGMENTS_CLASSES[i].getName());
            if (fragment != null) {
                ft.remove(fragment);
            }
        }
        ft.commitAllowingStateLoss();
    }

    /**
     * 延时mSlidingMenu.showContent()
     * 
     * @param delayMillis 延时时间 单位毫秒
     */
    private void postShowContent(long delayMillis) {
        handler.postDelayed(new Runnable() {

            @Override
            public void run() {
                if (mSlidingMenu!=null && !MainActivity.this.isFinishing()) {
                    mSlidingMenu.showContent();                 
                }
            }
        }, delayMillis);
    }
}

左边的fragment

package com.os.activity.sliding;

import java.util.Arrays;

import com.os.activity.MainActivity;
import com.os.activity.base.BaseSlidingFragment;
import com.os.slidingmenu.R;
import com.os.ui.FollowFragment;
import com.os.ui.MainHallFragment;
import com.os.ui.RankFragment;

import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;
public class LeftFragment extends BaseSlidingFragment {
    private final static int MENU_NORMAL_ICONS[] = {  R.drawable.sliding_livehall_icon_normal,
            R.drawable.sliding_follow_icon_normal, R.drawable.sliding_rank_icon_normal};

    private final static int MENU_CHECKED_ICONS[] = {  R.drawable.sliding_livehall_icon_checked,
            R.drawable.sliding_follow_icon_checked, R.drawable.sliding_rank_icon_checked };

    public final static Class[] FRAGMENTS_CLASSES = {  MainHallFragment.class, FollowFragment.class,
            RankFragment.class};//左侧切换显示中间的三个界面

    private View[] mMenuLayouts;
    private ImageView[] mMenuIcons;
    private TextView[] mMenuTexts;


    private Bitmap mLoadingBitmap;
    private int mCurrentIndex = -1;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.sliding_left);
        setData();
        changeMenuByClass(MainHallFragment.class);//默认中间的界面显示的是这个MainHallFragment


    }

    @Override
    public void initViews() {

        mMenuLayouts = new View[] { findViewById(R.id.menu_livehall_layout),
                findViewById(R.id.menu_follow_layout), findViewById(R.id.menu_rank_layout) };

        mMenuIcons = new ImageView[] {
                (ImageView) findViewById(R.id.menu_livehall_icon), (ImageView) findViewById(R.id.menu_follow_icon), (ImageView) findViewById(R.id.menu_rank_icon) };

        mMenuTexts = new TextView[] { 
                (TextView) findViewById(R.id.menu_livehall_text), (TextView) findViewById(R.id.menu_follow_text), (TextView) findViewById(R.id.menu_rank_text),};

    }

    @Override
    public void addListener() {



        for (int i = 0; i < mMenuLayouts.length; i++) {
            mMenuLayouts[i].setTag(i);
            mMenuLayouts[i].setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    int index = (Integer) v.getTag();
                    changeMenuByIndex(index);
                }
            });
        }
    }

    private void setData() {

    }






    /**
     * 通过索引改变Menu
     * 
     * @param index
     */
    @SuppressWarnings("unchecked")
    private void changeMenuByIndex(int index) {

        Class<? extends Fragment> clazz = null;
        if (mCurrentIndex != index) {
            clearMenu();
            setMenuChecked(index);
        }
        clazz = FRAGMENTS_CLASSES[index];
        getFragmentActivity(MainActivity.class).switchCenterFragment(clazz);
        mCurrentIndex = index;

    }

    /**
     * 通过Fragment类改变menu
     * 
     * @param clazz
     */
    public void changeMenuByClass(Class<? extends Fragment> clazz) {
        int index = Arrays.asList(FRAGMENTS_CLASSES).indexOf(clazz);
        if (index != -1) {
            changeMenuByIndex(index);

        }
    }


    @SuppressWarnings("deprecation")
    private void clearMenu() {
        for (int i = 1; i <= mMenuLayouts.length; i++) {
            mMenuLayouts[i-1].setBackgroundDrawable(null);
            mMenuIcons[i - 1].setImageResource(MENU_NORMAL_ICONS[i - 1]);
            mMenuTexts[i - 1].setTextColor(getResources().getColor(R.color.gray7));
        }
    }

    private void setMenuChecked(int index) {
//      if (index == 0) {
//          return;
//      }
        if (index != 1 && index != 2) {
            mMenuLayouts[index].setBackgroundResource(R.drawable.sliding_menu_checked_bg);
        }
        mMenuIcons[index ].setImageResource(MENU_CHECKED_ICONS[index ]);
        mMenuTexts[index ].setTextColor(getResources().getColor(R.color.white));
    }









    @Override
    public void onDestroy() {
        if (mLoadingBitmap != null && !mLoadingBitmap.isRecycled()) {
            mLoadingBitmap.recycle();
            mLoadingBitmap = null;
        }

        super.onDestroy();
    }
}

主要就是 oncreate 中 初始化 刚启动应用后中间显示的fragment 是 MainHallFragment.

视频时RTMP 协议,解码用的ffmpeg. 代码就不贴了,在工程的jni 目录下,都有注释。

聊天的代码 聊天室界面是 ChatroomActivity.

这是 一初始化MultiUserChat 聊天室对象的代码,具体代码 ,在这个类里面。

new Thread() {
            public void run() {
                try {
                    Thread.sleep(1 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                int count = 0;
                boolean isRandom = false;

                while (count <= 10 && !create_flag) {
                    count++;

                    try {
                        if (mHostInfo != null) {
                            mUserNickName = getNickName(isRandom);
                            muc = ConnectionUtils.getMultiUserChat(mHostInfo.room_id, mHostInfo.room_service, mUserNickName, mPassword, ChatroomActivity.this);

                            if (muc != null) {
                                create_flag = true;
                                // 创建聊天室成功,监听聊天室返回的消息
                                // 监听消息
                                muc.addMessageListener(packetListener);
                                // muc.addParticipantListener(participantListener);
                                muc.addParticipantStatusListener(statusListener);
                                muc.addUserStatusListener(userStatusListener);
                                mHandler.sendEmptyMessageDelayed(9, 500);
                            } else {
                                create_flag = false;
                            }
                        } else {
                            create_flag = false;
                        }
                        // } else {
                        //
                        // }
                    } catch (NotFoundException e) {
                        e.printStackTrace();
                    } catch (SameException e) {// 昵称重复
                        isRandom = true;
                    } catch (BannedException e) {// 禁止加入房间
                        sendBandHandle(15);
                        return;
                    } catch (XMPPException e) {
                        e.printStackTrace();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

具体业务代码,工程里面找吧。有需要的可以看下,找工作的时候用。关于项目的其他问题可以Q我。
对了,由于公司服务器停了,所以自己注册用户的借口也挂了,注册不成功,点击 那个一键注册的,还可以,就是发送一条短信息(1毛钱),然后就进入界面了。
PS: 反正服务器都停了,就贡献出来,找工作也算多个项目。
完整代码:http://download.csdn.net/detail/u011733020/8875855

版权声明:本文为博主原创文章,未经博主允许不得转载。

J哥---------公司(视频 社交)项目分享

标签:视频   社交应用   openfire   asmack   聊天室   

原文地址:http://blog.csdn.net/u011733020/article/details/46786471

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!