精华内容
下载资源
问答
  • Android 仿QQ主页面的实

    万次阅读 多人点赞 2012-11-11 20:45:47
    这一节讲一下QQ主页面的实现,先看一下官方效果图:其中的好友,群组等既可以点击切换也卡,也可以滑动切换。所以,在实现的时候要同时使用两个手段。“会话”,“好友”等可以用Button来写,也可以是RadioButton,...

      这一节讲一下QQ主页面的实现,先看一下官方效果图:


    其中的好友,群组等既可以点击切换也卡,也可以滑动切换。所以,在实现的时候要同时使用两个手段。“会话”,“好友”等可以用Button来写,也可以是RadioButton,还可以是TextView,方法很多,在这里我选择了用TextView来做。而且这里的TextView要支持颜色的切换,默认一个暗白色,页卡停留在那是白色。总体来说还是比较简单的,下面看一下xml布局文件:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainQQActivity" >
    
        <RelativeLayout
            android:id="@+id/headlayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/chat_bottom_send_pressed" >
    
            <ImageView
                android:id="@+id/stateimage"
                android:layout_width="13dp"
                android:layout_height="13dp"
                android:layout_toRightOf="@+id/nametext"
                android:layout_marginLeft="10dp"
                android:layout_centerInParent="true"
                android:contentDescription="wq"
                android:src="@drawable/onlinestatus_online" />
    
            <ImageView
                android:id="@+id/faceimage"
                android:layout_width="40dp"
                android:layout_height="40dp"
                android:layout_marginLeft="6dp"
                android:layout_marginTop="10dp"
                android:layout_alignParentLeft="true"
                android:layout_centerVertical="true"
                android:src="@drawable/qq" />
    
            <TextView
                android:id="@+id/nametext"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginLeft="14dp"
                android:layout_toRightOf="@+id/faceimage"
                android:text="JY"
                android:textColor="@color/color_bai"
                android:textSize="18dp" />
        </RelativeLayout>//这个Layout是最上面的头像,名称以及状态的布局。当然,也可以用LinearLayout来做。
    
        <LinearLayout 
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/login_moremenu_back"
            android:orientation="vertical"
            >
        <LinearLayout//这个LinearLayout用来显示四个标题
            android:id="@+id/bodylayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/login_moremenu_back"
            android:orientation="horizontal" >
    
            <TextView
                android:id="@+id/speaktext"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="5dp"
                android:layout_marginTop="5dp"
                android:layout_weight="1"
                android:gravity="center"
                android:text="会话"
                android:textColor="@drawable/text_color"
                android:textSize="18dp" />
    
            <TextView
                android:id="@+id/fridenttext"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="5dp"
                android:layout_marginTop="5dp"
                android:layout_weight="1"
                android:gravity="center"
                android:text="好友"
                android:textColor="@drawable/text_color"
                android:textSize="18dp" />
    
            <TextView
                android:id="@+id/grouptext"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="5dp"
                android:layout_marginTop="5dp"
                android:layout_weight="1"
                android:gravity="center"
                android:text="群组"
                android:textColor="@drawable/text_color"
                android:textSize="18dp" />
    
            <TextView
                android:id="@+id/changetext"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="5dp"
                android:layout_marginTop="5dp"
                android:layout_weight="1"
                android:gravity="center"
                android:text="动态"
                android:textColor="@drawable/text_color"
                android:textSize="18dp" />
        </LinearLayout>
        
        <ImageView//这个就是下面的横杠图片
            android:id="@+id/cursor"
            android:layout_width="50dp"
            android:layout_height="6dp"
            android:layout_marginLeft="15dp"
            android:src="@drawable/meitu" />
        
        </LinearLayout>
    
        
    
        <android.support.v4.view.ViewPager//不解释,用来滑动页卡
            android:id="@+id/vPager"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:layout_gravity="center"
            android:layout_weight="1.0"
            android:background="#000000"
            android:flipInterval="30"
            android:persistentDrawingCache="animation" />
    
    </LinearLayout>

     有了上一篇《Android ViewPager使用详解 》的基础 ,Activity的代码就很容易理解了,我就不注释了。看一下Activity代码:

    package com.example.imitateqq;
    
    import java.util.ArrayList;
    import java.util.List;
    import android.app.Activity;
    import android.graphics.BitmapFactory;
    import android.graphics.Matrix;
    import android.os.Bundle;
    import android.support.v4.view.PagerAdapter;
    import android.support.v4.view.ViewPager;
    import android.support.v4.view.ViewPager.OnPageChangeListener;
    import android.util.DisplayMetrics;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.Window;
    import android.view.View.OnClickListener;
    import android.view.animation.Animation;
    import android.view.animation.TranslateAnimation;
    import android.view.ViewGroup;
    import android.widget.ImageView;
    import android.widget.TextView;
    
    public class MainQQActivity extends Activity {
    
    	private ViewPager viewPager;
    	private ImageView imageView;
    	private TextView textView1, textView2, textView3, textView4;
    	private View view1, view2, view3, view4;
    	private List<View> views;
    	private int offSet = 0;// 动画图片偏移量
    	private int currIndex = 0;// 当前页卡编号
    	private int bmpW;// 动画图片宽度
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    		setContentView(R.layout.mainqq);
    		initView();
    		initListener();
    	}
    
    	private void initView() {
    		viewPager = (ViewPager) findViewById(R.id.vPager);
    		imageView = (ImageView) findViewById(R.id.cursor);
    
    		textView1 = (TextView) findViewById(R.id.speaktext);
    		textView2 = (TextView) findViewById(R.id.fridenttext);
    		textView3 = (TextView) findViewById(R.id.grouptext);
    		textView4 = (TextView) findViewById(R.id.changetext);
    
    		LayoutInflater layoutInflater = getLayoutInflater();
    		view1 = layoutInflater.inflate(R.layout.qqtab_1, null);
    		view2 = layoutInflater.inflate(R.layout.qqtab_2, null);
    		view3 = layoutInflater.inflate(R.layout.qqtab_3, null);
    		view4 = layoutInflater.inflate(R.layout.qqtab_4, null);
    
    		views = new ArrayList<View>();
    		views.add(view1);
    		views.add(view2);
    		views.add(view3);
    		views.add(view4);
    
    		bmpW=BitmapFactory.decodeResource(getResources(), R.drawable.a).getWidth();
    		DisplayMetrics displayMetrics=new DisplayMetrics();
    		getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
    		int screenW=displayMetrics.widthPixels;
    		offSet=(screenW / 4 - bmpW) / 2;
    		Matrix matrix=new Matrix();
    		matrix.postTranslate(screenW, 0);
    		imageView.setImageMatrix(matrix);
    	}
    
    	private void initListener() {
    		textView1.setOnClickListener(new MyOnClickListener(0));
    		textView2.setOnClickListener(new MyOnClickListener(1));
    		textView3.setOnClickListener(new MyOnClickListener(2));
    		textView4.setOnClickListener(new MyOnClickListener(3));
    
    		viewPager.setAdapter(new MyPagerAdapter(views));
    		viewPager.setOnPageChangeListener(new MyOnPageChangeListener());
    		viewPager.setCurrentItem(0);
    		textView1.setTextColor(getResources().getColor(R.color.color_bai));
    	}
    
    	private class MyPagerAdapter extends PagerAdapter {
    		private List<View> mListViews;
    
    		public MyPagerAdapter(List<View> mListViews) {
    			this.mListViews = mListViews;
    		}
    
    		@Override
    		public void destroyItem(ViewGroup container, int position, Object object) {
    			container.removeView(mListViews.get(position));
    		}
    
    		@Override
    		public Object instantiateItem(ViewGroup container, int position) {
    			container.addView(mListViews.get(position));
    			return mListViews.get(position);
    		}
    
    		@Override
    		public int getCount() {
    			return mListViews.size();
    		}
    
    		@Override
    		public boolean isViewFromObject(View arg0, Object arg1) {
    			return arg0 == arg1;
    		}
    
    	}
    
    	private class MyOnPageChangeListener implements OnPageChangeListener {
    		int one = offSet * 2 + bmpW;// 页卡1 -> 页卡2 偏移量
    		
    		public void onPageScrollStateChanged(int arg0) {
    			
    
    		}
    
    		public void onPageScrolled(int arg0, float arg1, int arg2) {
    			
    
    		}
    
    		public void onPageSelected(int arg0) {
    			Animation animation = new TranslateAnimation(one*currIndex, one*arg0, 0, 0);
    			currIndex = arg0;
    			animation.setFillAfter(true);// True:图片停在动画结束位置
    			animation.setDuration(300);
    			imageView.startAnimation(animation);
    			switch(currIndex){
    			case 0:
    				textView1.setTextColor(getResources().getColor(R.color.color_bai));
    				textView2.setTextColor(getResources().getColor(R.color.title_bg));
    				textView3.setTextColor(getResources().getColor(R.color.title_bg));
    				textView4.setTextColor(getResources().getColor(R.color.title_bg));
    				break;
    			case 1:
    				textView2.setTextColor(getResources().getColor(R.color.color_bai));
    				textView1.setTextColor(getResources().getColor(R.color.title_bg));
    				textView3.setTextColor(getResources().getColor(R.color.title_bg));
    				textView4.setTextColor(getResources().getColor(R.color.title_bg));
    				break;
    			case 2:
    				textView3.setTextColor(getResources().getColor(R.color.color_bai));
    				textView2.setTextColor(getResources().getColor(R.color.title_bg));
    				textView1.setTextColor(getResources().getColor(R.color.title_bg));
    				textView4.setTextColor(getResources().getColor(R.color.title_bg));
    				break;
    			case 3:
    				textView4.setTextColor(getResources().getColor(R.color.color_bai));
    				textView2.setTextColor(getResources().getColor(R.color.title_bg));
    				textView3.setTextColor(getResources().getColor(R.color.title_bg));
    				textView1.setTextColor(getResources().getColor(R.color.title_bg));
    				default :
    					break;
    			}
    		}
    
    	}
    
    	private class MyOnClickListener implements OnClickListener {
    		private int index = 0;
    
    		public MyOnClickListener(int i) {
    			index = i;
    		}
    
    		public void onClick(View v) {
    			viewPager.setCurrentItem(index);
    			
    			switch(index){
    			case 0:
    				textView1.setTextColor(getResources().getColor(R.color.color_bai));
    				textView2.setTextColor(getResources().getColor(R.color.title_bg));
    				textView3.setTextColor(getResources().getColor(R.color.title_bg));
    				textView4.setTextColor(getResources().getColor(R.color.title_bg));
    				break;
    			case 1:
    				textView2.setTextColor(getResources().getColor(R.color.color_bai));
    				textView1.setTextColor(getResources().getColor(R.color.title_bg));
    				textView3.setTextColor(getResources().getColor(R.color.title_bg));
    				textView4.setTextColor(getResources().getColor(R.color.title_bg));
    				break;
    			case 2:
    				textView3.setTextColor(getResources().getColor(R.color.color_bai));
    				textView2.setTextColor(getResources().getColor(R.color.title_bg));
    				textView1.setTextColor(getResources().getColor(R.color.title_bg));
    				textView4.setTextColor(getResources().getColor(R.color.title_bg));
    				break;
    			case 3:
    				textView4.setTextColor(getResources().getColor(R.color.color_bai));
    				textView2.setTextColor(getResources().getColor(R.color.title_bg));
    				textView3.setTextColor(getResources().getColor(R.color.title_bg));
    				textView1.setTextColor(getResources().getColor(R.color.title_bg));
    				default :
    					break;
    			}
    			
    		}
    
    	}
    }
    


     最后看一下效果图:

      关于QQ的UI部分基本上就是这样,之后将引入服务器,实现通信的功能。当然,还有很多UI要写,比如聊天页面,设置页面等等,在用到的时候再去写。谢谢大家关注!

      下载地址

    展开全文
  • 今天模仿安卓QQ空间,打开程序的启动画面和导航页面我就不做了,大家可以模仿微信的那个做一下,很简单。这次主要做一下主页面的实现,感兴趣的朋友可以参考下
  • 主要为大家详细介绍了Android仿QQ6.0主页面侧滑效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 仿QQ6.0主页面侧滑效果

    万次阅读 热门讨论 2016-11-02 01:31:52
    1.概述 最近一直都在带实习生做项目,发现自己好久没有写博客了,这几天更新会比较频繁,今天玩QQ的时候发现QQ主页菜单滑动效果早就变了,实在忍不住晚上就来实现一下了! 2.实现 2.1. 实现的方式多种多样  ...

    1.概述


      最近一直都在带实习生做项目,发现自己好久没有写博客了,这几天更新会比较频繁,今天玩QQ的时候发现QQ主页菜单滑动效果早就变了,实在忍不住晚上就来实现一下了! 这里我已经写得很详细了如果大家还是看不太懂请看视频讲解:http://pan.baidu.com/s/1eS1bdLK
      
      这里写图片描述

    2.实现 


      2.1. 实现的方式多种多样
      2.1.1 自定义ViewGroup ,处理其onTouch事件
      2.1.2 FrameLayout + 手势处理类GestureDetector
      2.2.3 使用Google自带的DrawerLayout 对其进行修改
      2.2.4 继承自水平滚动HorizontalScrollView
    大家可以看一下这个http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2016/0909/6612.html,这种方式继承自ViewGroup,个人觉得还行但是还是比较繁琐要处理的东西也比较多,那么我就用最后一种2.2.4的方式实现,有人说直接去网上下载一个源代码就可以了,这我就只能GG了。

      2.3. 自定义SlidingMenu extends HorizontalScrollView 然后写好布局文件这个和ScrollView的用法一样,只不过是横向滚动的

    /**
     * description:
     *      仿QQ6.0主页面侧滑的自定View
     * Created by 曾辉 on 2016/11/1.
     * QQ:240336124
     * Email: 240336124@qq.com
     * Version:1.0
     */
    public class SlidingMenu extends HorizontalScrollView {
        public SlidingMenu(Context context) {
            super(context);
        }
    
        public SlidingMenu(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public SlidingMenu(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    }

    2.4. 运行起来之后发现布局不对,完全乱了明明都是match_parent可是就是不行那么我们就需要用代码指定菜单和内容的宽度:
    菜单的宽度 = 屏幕的宽度 - 自定义的右边留出的宽度
    内容的宽度 = 屏幕的宽度

    /**
     * description:
     *      仿QQ6.0主页面侧滑的自定View
     * Created by 曾辉 on 2016/11/1.
     * QQ:240336124
     * Email: 240336124@qq.com
     * Version:1.0
     */
    public class SlidingMenu extends HorizontalScrollView {
        private View mMenuView;
        private View mContentView;
        private int mMenuWidth;
    
        public SlidingMenu(Context context) {
            this(context, null);
        }
    
        public SlidingMenu(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public SlidingMenu(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            // 获取自定义的右边留出的宽度
            TypedArray array = context.obtainStyledAttributes(attrs,R.styleable.SlidingMenu);
            float rightPadding = array.getDimension(
                    R.styleable.SlidingMenu_rightPadding,dip2px(50));
            // 计算菜单的宽度 = 屏幕的宽度 - 自定义右边留出的宽度
            mMenuWidth = (int) (getScreenWidth() - rightPadding);
            array.recycle();
        }
    
        /**
         * 把dip 转成像素
         */
        private float dip2px(int dip) {
            return TypedValue.applyDimension(
                    TypedValue.COMPLEX_UNIT_DIP,dip,getResources().getDisplayMetrics());
        }
    
    
        @Override
        protected void onFinishInflate() {
            super.onFinishInflate();
    
            // 1.获取根View也就是外层的LinearLayout
            ViewGroup container = (ViewGroup) this.getChildAt(0);
    
            int containerChildCount = container.getChildCount();
            if(containerChildCount>2){
                // 里面只允许放置两个布局  一个是Menu(菜单布局) 一个是Content(主页内容布局)
                throw new IllegalStateException("SlidingMenu 根布局LinearLayout下面只允许两个布局,菜单布局和主页内容布局");
            }
    
            // 2.获取菜单和内容布局
            mMenuView = container.getChildAt(0);
            mContentView = container.getChildAt(1);
    
            // 3.指定内容和菜单布局的宽度
            // 3.1 菜单的宽度 = 屏幕的宽度 - 自定义的右边留出的宽度
            mMenuView.getLayoutParams().width = mMenuWidth;
            // 3.2 内容的宽度 = 屏幕的宽度
            mContentView.getLayoutParams().width = getScreenWidth();
        }
    
        /**
         * 获取屏幕的宽度
         */
        public int getScreenWidth() {
            Resources resources = this.getResources();
            DisplayMetrics dm = resources.getDisplayMetrics();
            return dm.widthPixels;
        }
    }

    目前的效果就是可以滑动,并且菜单和主页面内容的布局宽度正常

    这里写图片描述

      2.5 接下来一开始就让菜单滑动到关闭状态,手指滑动抬起判断菜单打开和关闭并做相应的处理 onLayout() onTouch() smoothScrollTo(),当手指快速的时候切换菜单的状态利用GestureDetector 手势处理类:

        /**
     * description:
     * 仿QQ6.0主页面侧滑的自定View
     * Created by 曾辉 on 2016/11/1.
     * QQ:240336124
     * Email: 240336124@qq.com
     * Version:1.0
     */
    public class SlidingMenu extends HorizontalScrollView {
        private View mMenuView;
        private View mContentView;
        private int mMenuWidth;
        // 手势处理类 主要用来处理手势快速滑动
        private GestureDetector mGestureDetector;
    
        // 菜单是否打开
        private boolean mMenuIsOpen = false;
    
        public SlidingMenu(Context context) {
            this(context, null);
        }
    
        public SlidingMenu(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public SlidingMenu(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            // 获取自定义的右边留出的宽度
            TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.SlidingMenu);
            float rightPadding = array.getDimension(
                    R.styleable.SlidingMenu_rightPadding, dip2px(50));
            // 计算菜单的宽度 = 屏幕的宽度 - 自定义右边留出的宽度
            mMenuWidth = (int) (getScreenWidth() - rightPadding);
            array.recycle();
    
            // 实例化手势处理类
            mGestureDetector = new GestureDetector(context,new GestureListener());
        }
    
        /**
         * 把dip 转成像素
         */
        private float dip2px(int dip) {
            return TypedValue.applyDimension(
                    TypedValue.COMPLEX_UNIT_DIP, dip, getResources().getDisplayMetrics());
        }
    
    
        @Override
        protected void onFinishInflate() {
            super.onFinishInflate();
    
            // 1.获取根View也就是外层的LinearLayout
            ViewGroup container = (ViewGroup) this.getChildAt(0);
    
            int containerChildCount = container.getChildCount();
            if (containerChildCount > 2) {
                // 里面只允许放置两个布局  一个是Menu(菜单布局) 一个是Content(主页内容布局)
                throw new IllegalStateException("SlidingMenu 根布局LinearLayout下面只允许两个布局,菜单布局和主页内容布局");
            }
    
            // 2.获取菜单和内容布局
            mMenuView = container.getChildAt(0);
            mContentView = container.getChildAt(1);
    
            // 3.指定内容和菜单布局的宽度
            // 3.1 菜单的宽度 = 屏幕的宽度 - 自定义的右边留出的宽度
            mMenuView.getLayoutParams().width = mMenuWidth;
            // 3.2 内容的宽度 = 屏幕的宽度
            mContentView.getLayoutParams().width = getScreenWidth();
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent ev) {
    
            // 处理手指快速滑动
            if(mGestureDetector.onTouchEvent(ev)){
                return mGestureDetector.onTouchEvent(ev);
            }
    
            switch (ev.getAction()) {
                case MotionEvent.ACTION_UP:
                    // 手指抬起获取滚动的位置
                    int currentScrollX = getScrollX();
                    if (currentScrollX > mMenuWidth / 2) {
                        // 关闭菜单
                        closeMenu();
                    } else {
                        // 打开菜单
                        openMenu();
                    }
                    return false;
            }
            return super.onTouchEvent(ev);
        }
    
        /**
         * 打开菜单
         */
        private void openMenu() {
            smoothScrollTo(0, 0);
            mMenuIsOpen = true;
        }
    
        /**
         * 关闭菜单
         */
        private void closeMenu() {
            smoothScrollTo(mMenuWidth, 0);
            mMenuIsOpen = false;
        }
    
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            super.onLayout(changed, l, t, r, b);
            // 布局指定后会从新摆放子布局,当其摆放完毕后,让菜单滚动到不可见状态
            if (changed) {
                scrollTo(mMenuWidth, 0);
            }
        }
    
        /**
         * 获取屏幕的宽度
         */
        public int getScreenWidth() {
            Resources resources = this.getResources();
            DisplayMetrics dm = resources.getDisplayMetrics();
            return dm.widthPixels;
        }
    
    
        private class GestureListener extends GestureDetector.SimpleOnGestureListener{
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                // 当手指快速滑动时候回调的方法
                Log.e("TAG",velocityX+"");
                // 如果菜单打开 并且是向左快速滑动 切换菜单的状态
                if(mMenuIsOpen){
                    if(velocityX<-500){
                        toggleMenu();
                        return true;
                    }
                }else{
                    // 如果菜单关闭 并且是向右快速滑动 切换菜单的状态
                    if(velocityX>500){
                        toggleMenu();
                        return true;
                    }
                }
    
                return false;
            }
        }
    
        /**
         * 切换菜单的状态
         */
        private void toggleMenu() {
            if(mMenuIsOpen){
                closeMenu();
            }else{
                openMenu();
            }
        }
    }

    到了这一步之后我们就可以切换菜单了,并且处理了手指快速滑动,迫不及待的看下效果

    这里写图片描述

    2.6. 实现菜单左边抽屉样式的动画效果,监听滚动回调的方法onScrollChanged() 这个就非常简单了一句话就搞定,效果就不看了一起看终极效果吧

    @Override
        protected void onScrollChanged(int l, int t, int oldl, int oldt) {
            super.onScrollChanged(l, t, oldl, oldt);
    
            // l 是 当前滚动的x距离  在滚动的时候会不断反复的回调这个方法
            Log.e(TAG,l+"");
    
            mMenuView.setTranslationX(l*0.8f);
        }

    2.7. 实现菜单右边菜单的阴影透明度效果,这个打算在主页面内容布局上面加一层阴影,用ImageView即可,那么我们的内容View就需要换了

    /**
     * description:
     * 仿QQ6.0主页面侧滑的自定View
     * Created by 曾辉 on 2016/11/1.
     * QQ:240336124
     * Email: 240336124@qq.com
     * Version:1.0
     */
    public class SlidingMenu extends HorizontalScrollView {
        private static final String TAG = "HorizontalScrollView";
        private Context mContext;
    
        // 4.给菜单和内容View指定宽高 - 左边菜单View
        private View mMenuView;
    
        // 4.给菜单和内容View指定宽高 - 菜单的宽度
        private int mMenuWidth;
        // 5.3 手势处理类 主要用来处理手势快速滑动
        private GestureDetector mGestureDetector;
        // 5.3 菜单是否打开
        private boolean mMenuIsOpen = false;
    
        // 7(4). 主页面内容View的布局包括阴影ImageView
        private ViewGroup mContentView;
        // 7.给内容添加阴影效果 - 阴影的ImageView
        private ImageView mShadowIv;
    
        public SlidingMenu(Context context) {
            this(context, null);
        }
    
        public SlidingMenu(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public SlidingMenu(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            //4.1 计算左边菜单的宽度
            //4.1.1 获取自定义的右边留出的宽度
            TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.SlidingMenu);
            float rightPadding = array.getDimension(
                    R.styleable.SlidingMenu_rightPadding, dip2px(50));
            // 4.1.2 计算菜单的宽度 = 屏幕的宽度 - 自定义右边留出的宽度
            mMenuWidth = (int) (getScreenWidth() - rightPadding);
            array.recycle();
    
            // 5.3 实例化手势处理类
            mGestureDetector = new GestureDetector(context,new GestureListener());
    
            this.mContext = context;
        }
    
        /**
         * 把dip 转成像素
         */
        private float dip2px(int dip) {
            return TypedValue.applyDimension(
                    TypedValue.COMPLEX_UNIT_DIP, dip, getResources().getDisplayMetrics());
        }
    
    
        @Override
        protected void onFinishInflate() {
            super.onFinishInflate();
            // 4.2 指定菜单和内容View的宽度
            // 4.2.1.获取根View也就是外层的LinearLayout
            ViewGroup container = (ViewGroup) this.getChildAt(0);
    
            int containerChildCount = container.getChildCount();
            if (containerChildCount > 2) {
                // 里面只允许放置两个布局  一个是Menu(菜单布局) 一个是Content(主页内容布局)
                throw new IllegalStateException("SlidingMenu 根布局LinearLayout下面只允许两个布局,菜单布局和主页内容布局");
            }
    
            // 4.2.2.获取菜单和内容布局
            mMenuView = container.getChildAt(0);
    
            // 7.给内容添加阴影效果
            // 7.1 先new一个主内容布局用来放  阴影和LinearLayout原来的内容布局
            mContentView = new FrameLayout(mContext);
            ViewGroup.LayoutParams contentParams = new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
    
            // 7.2 获取原来的内容布局,并把原来的内容布局从LinearLayout中异常
            View oldContentView = container.getChildAt(1);
            container.removeView(oldContentView);
    
            // 7.3 把原来的内容View 和 阴影加到我们新创建的内容布局中
            mContentView.addView(oldContentView);
            // 7.3.1 创建阴影ImageView
            mShadowIv = new ImageView(mContext);
            mShadowIv.setBackgroundColor(Color.parseColor("#99000000"));
            mContentView.addView(mShadowIv);
    
            // 7.4 把包含阴影的新的内容View 添加到 LinearLayout中
            container.addView(mContentView);
    
            // 4.2.3.指定内容和菜单布局的宽度
            // 4.2.3.1 菜单的宽度 = 屏幕的宽度 - 自定义的右边留出的宽度
            mMenuView.getLayoutParams().width = mMenuWidth;
            // 4.2.3.2 内容的宽度 = 屏幕的宽度
            mContentView.getLayoutParams().width = getScreenWidth();
        }
    
        /**
         * 5.处理手指抬起和快速滑动切换菜单
         */
        @Override
        public boolean onTouchEvent(MotionEvent ev) {
            // 5.3 处理手指快速滑动
            if(mGestureDetector.onTouchEvent(ev)){
                return mGestureDetector.onTouchEvent(ev);
            }
    
            switch (ev.getAction()) {
                case MotionEvent.ACTION_UP:
                    // 5.1 手指抬起获取滚动的位置
                    int currentScrollX = getScrollX();
                    if (currentScrollX > mMenuWidth / 2) {
                        // 5.1.1 关闭菜单
                        closeMenu();
                    } else {
                        // 5.1.2 打开菜单
                        openMenu();
                    }
                    return false;
            }
            return super.onTouchEvent(ev);
        }
    
        @Override
        protected void onScrollChanged(int l, int t, int oldl, int oldt) {
            super.onScrollChanged(l, t, oldl, oldt);
    
            // l 是 当前滚动的x距离  在滚动的时候会不断反复的回调这个方法
            Log.e(TAG,l+"");
            // 6. 实现菜单左边抽屉样式的动画效果
            mMenuView.setTranslationX(l*0.8f);
    
            // 7.给内容添加阴影效果 - 计算梯度值
            float gradientValue = l * 1f / mMenuWidth;// 这是  1 - 0 变化的值
    
            // 7.给内容添加阴影效果 - 给阴影的View指定透明度   0 - 1 变化的值
            float shadowAlpha = 1 - gradientValue;
            mShadowIv.setAlpha(shadowAlpha);
        }
    
        /**
         * 5.1.2 打开菜单
         */
        private void openMenu() {
            smoothScrollTo(0, 0);
            mMenuIsOpen = true;
        }
    
        /**
         * 5.1.1 关闭菜单
         */
        private void closeMenu() {
            smoothScrollTo(mMenuWidth, 0);
            mMenuIsOpen = false;
        }
    
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            super.onLayout(changed, l, t, r, b);
            // 布局指定后会从新摆放子布局,当其摆放完毕后,让菜单滚动到不可见状态
            if (changed) {
                scrollTo(mMenuWidth, 0);
            }
        }
    
        /**
         * 获取屏幕的宽度
         */
        public int getScreenWidth() {
            Resources resources = this.getResources();
            DisplayMetrics dm = resources.getDisplayMetrics();
            return dm.widthPixels;
        }
    
    
        /**
         * 5.3 处理手指快速滑动
         */
        private class GestureListener extends GestureDetector.SimpleOnGestureListener{
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                // 当手指快速滑动时候回调的方法
                Log.e(TAG,velocityX+"");
                // 5.3.1 如果菜单打开 并且是向左快速滑动 切换菜单的状态
                if(mMenuIsOpen){
                    if(velocityX<0){
                        toggleMenu();
                        return true;
                    }
                }else{
                    // 5.3.2 如果菜单关闭 并且是向右快速滑动 切换菜单的状态
                    if(velocityX>0){
                        toggleMenu();
                        return true;
                    }
                }
                return false;
            }
        }
    
        /**
         * 切换菜单的状态
         */
        private void toggleMenu() {
            if(mMenuIsOpen){
                closeMenu();
            }else{
                openMenu();
            }
        }
    }

    我们来看一下最后的效果吧,最终代码量不是很多啦,需要的请下载源码,如果是实现QQ5.0或是酷狗的侧滑效果可以自己改改,也可以加我QQ或是留言给我

    这里写图片描述

    附源码地址:http://download.csdn.net/detail/z240336124/9670554

    展开全文
  • Test_QQMainView 通过 OC 实现“手机QQ主页面的侧滑菜单、视图联动
  • 仿qq的jsp页面

    2014-12-05 19:08:53
    模仿qq的一个聊天界面,使用jsp进行开发
  • 主页面设置: 先导入 &lt;common:resourse url = "/system/js/showModalDialog.js"/&gt; js标签 作用 就是 将打开的窗口 有返回值    var url = "'; //弹窗的URL  var ...

    主页面设置:

    先导入 <common:resourse url = "/system/js/showModalDialog.js"/>  js标签

    作用 就是 将打开的窗口 有返回值

     

       var  url = "';  //弹窗的URL

        var  resultText = window.showModalDialog(url,"","dialogWidth=850px","dialogHeight=800px");

         if (resultText  == 'success') {

            var  URL = “”;  //刷新主页面的URL

         var   oProject = $("#allPeojectFrom").attr("action",URL);

    oProject .submint();

    }

     

     

    弹窗页面设置

    var  result = "success";

     // 关闭窗口时向父页面返回参数

     window.onberforeunload = function () {

        window.returnValue = result ;

    }

    //关闭窗口

    function closeWindow () {

    window.close();

    }

    function save (){

    url请求后台返回参数,可以ajax请求 也可以正常请求

    判断参数

    if (date== 'success') {

    result = date;      //这里注意不能和返回参数名称一样  要不返回值访问不到。

    window.onberforeunload();

    closeWindow ();

    }

    //还有什么不懂得请加QQ2337594954 

     

    展开全文
  • Qt之模仿QQ主面板界面

    千次阅读 多人点赞 2018-03-28 14:41:01
    Qt之模仿QQ主面板界面 Qt之模仿QQ主面板界面 效果图 结尾 效果图 这里大家值得注意的是,QQ等级设置,已经列表展开搜索时的三角符的旋转效果 //QQMainWindow.cpp #include "...

    Qt之模仿QQ主面板界面

    效果图

    这里写图片描述

    这里写图片描述

    这里写图片描述

    这里大家值得注意的是,QQ等级设置,已经列表展开搜索时的三角符的旋转效果

    这里写图片描述

    //QQMainWindow.cpp
    #include "qqmainwindow.h"
    #include "contactitem.h"
    #include "rootcontatitem.h"
    #include "skinwindow.h"
    
    #include <QPainter>
    #include <QMouseEvent>
    #include <QSpacerItem>
    #include <QProxyStyle>
    #include <QTimer>
    
    class CustomProxyStyle : public QProxyStyle
    {
    public:
        virtual void drawPrimitive(PrimitiveElement element, const QStyleOption * option,
            QPainter * painter, const QWidget * widget = 0) const
        {
            if (PE_FrameFocusRect == element)
            {
                return;
            }
            else
            {
                QProxyStyle::drawPrimitive(element, option, painter, widget);
            }
        }
    };
    
    QQMainWindow::QQMainWindow(QWidget *parent)
        : BasicWindow(parent)
    {
        ui.setupUi(this);
        m_styleName = "MainWindow";
        loadStyleSheet("MainWindow");
        initControl();
    
        QTimer* timer = new QTimer(this);
        timer->setInterval(500);
        connect(timer, &QTimer::timeout, [this](){
            static int level = 0;
            if (level == 99)
            {
                level = 0;
            }
            setLevelPixmap(level);
            level++;
        });
        timer->start();
    }
    
    QQMainWindow::~QQMainWindow()
    {
    
    }
    
    void QQMainWindow::initControl()
    {
        ui.treeWidget->setStyle(new CustomProxyStyle);
    
        setLevelPixmap(0);
        setUserName(QString::fromLocal8Bit("雨田哥-工作号"));
        setHeadPixmap(":/QQMainWindow/Resources/MainWindow/yutiange.jpg");
        setStatusMenuIcon(":/QQMainWindow/Resources/MainWindow/StatusSucceeded.png");
    
        QHBoxLayout *flowLayout = new QHBoxLayout();
        flowLayout->setContentsMargins(0, 0, 0, 0);
        flowLayout->setSpacing(2);
        flowLayout->addWidget(addOtherAppExtension(":/QQMainWindow/Resources/MainWindow/app/app_7.png", "app_7"));
        flowLayout->addWidget(addOtherAppExtension(":/QQMainWindow/Resources/MainWindow/app/app_2.png", "app_2"));
        flowLayout->addWidget(addOtherAppExtension(":/QQMainWindow/Resources/MainWindow/app/app_3.png", "app_3"));
        flowLayout->addWidget(addOtherAppExtension(":/QQMainWindow/Resources/MainWindow/app/app_4.png", "app_4"));
        flowLayout->addWidget(addOtherAppExtension(":/QQMainWindow/Resources/MainWindow/app/app_5.png", "app_5"));
        flowLayout->addWidget(addOtherAppExtension(":/QQMainWindow/Resources/MainWindow/app/app_6.png", "app_6"));
        flowLayout->addStretch();
        flowLayout->addWidget(addOtherAppExtension(":/QQMainWindow/Resources/MainWindow/app/skin.png", "app_skin"));
        ui.appWidget->setLayout(flowLayout);
    
        ui.bottomLayout_up->addWidget(addOtherAppExtension(":/QQMainWindow/Resources/MainWindow/app/app_10.png", "app_10"));
        ui.bottomLayout_up->addWidget(addOtherAppExtension(":/QQMainWindow/Resources/MainWindow/app/app_8.png", "app_8"));
        ui.bottomLayout_up->addWidget(addOtherAppExtension(":/QQMainWindow/Resources/MainWindow/app/app_11.png", "app_11"));
        ui.bottomLayout_up->addWidget(addOtherAppExtension(":/QQMainWindow/Resources/MainWindow/app/app_9.png", "app_9"));
        ui.bottomLayout_up->addStretch();
    
        ui.lineEdit->installEventFilter(this);
        ui.searchLineEdit->installEventFilter(this);
    
        initContactTree();
        initStrangerTree();
    
        connect(ui.sysmin, SIGNAL(clicked(bool)), this, SLOT(onShowMin(bool)));
        connect(ui.sysclose, SIGNAL(clicked(bool)), this, SLOT(onShowClose(bool)));
    }
    
    void QQMainWindow::setHeadPixmap(const QString& headPath)
    {
        ui.headLabel->setPixmap(getRoundImage(QPixmap(headPath), QPixmap(":/QQMainWindow/Resources/MainWindow/head_mask.png"), ui.headLabel->size()));
    }
    
    void QQMainWindow::setUserName(const QString& username)
    {
        ui.nameLabel->adjustSize();
        QString name = ui.nameLabel->fontMetrics().elidedText(username, Qt::ElideRight, ui.nameLabel->width());
        ui.nameLabel->setText(name);
    }
    
    void QQMainWindow::setStatusMenuIcon(const QString& statusPath)
    {
        QPixmap statusBtnPixmap(ui.statusBtn->size());
        statusBtnPixmap.fill(Qt::transparent);
        QPainter painter(&statusBtnPixmap);
        painter.drawPixmap(4, 4, QPixmap(statusPath));
        painter.drawPixmap(16, 3, QPixmap(":/QQMainWindow/Resources/MainWindow/arrow_normal.gft.png"));
        ui.statusBtn->setIcon(statusBtnPixmap);
        ui.statusBtn->setIconSize(ui.statusBtn->size());
    }
    
    void QQMainWindow::setLevelPixmap(int level)
    {
        QPixmap levelPixmap(ui.levelBtn->size());
        levelPixmap.fill(Qt::transparent);
        QPainter painter(&levelPixmap);
        painter.drawPixmap(0, 4, QPixmap(":/QQMainWindow/Resources/MainWindow/lv.png"));
        int unitNum = level / 1 % 10;//取个位数字
        int tenNum = level / 10 % 10;//取十位数字
        //十位
        painter.drawPixmap(10, 4, QPixmap(":/QQMainWindow/Resources/MainWindow/levelvalue.png"), tenNum * 6, 0, 6, 7);
        //个位
        painter.drawPixmap(16, 4, QPixmap(":/QQMainWindow/Resources/MainWindow/levelvalue.png"), unitNum * 6, 0, 6, 7);
        ui.levelBtn->setIcon(levelPixmap);
        ui.levelBtn->setIconSize(ui.levelBtn->size());
    }
    
    QWidget* QQMainWindow::addOtherAppExtension(const QString& apppath, const QString& appName)
    {
        QPushButton* btn = new QPushButton(this);
        btn->setFixedSize(20, 20);
        QPixmap pixmap(btn->size());
        pixmap.fill(Qt::transparent);
        QPainter painter(&pixmap);
        QPixmap appPixmap(apppath);
        painter.drawPixmap((btn->width() - appPixmap.width()) / 2, (btn->height() - appPixmap.height())/2, appPixmap);
        btn->setIcon(pixmap);
        btn->setIconSize(btn->size());
        btn->setProperty("hasborder", true);
        btn->setObjectName(appName);
        connect(btn, &QPushButton::clicked, this, &QQMainWindow::onAppIconCliked);
        return btn;
    }
    
    void QQMainWindow::onAppIconCliked()
    {
        if (sender()->objectName() == "app_skin")
        {
            SkinWindow* skinWindow = new SkinWindow();
            skinWindow->show();
        }
    }
    
    void QQMainWindow::resizeEvent(QResizeEvent *event)
    {
        setUserName(QString::fromLocal8Bit("雨田哥-工作号"));
        __super::resizeEvent(event);
    }
    
    bool QQMainWindow::eventFilter(QObject *obj, QEvent *event)
    {
        if (ui.searchLineEdit == obj)
        {
            if (event->type() == QEvent::FocusIn)
            {
                ui.searchWidget->setStyleSheet("QWidget#searchWidget {background-color:rgb(255, 255, 255);}\
                                                QPushButton#searchBtn {border-image:url(:/QQMainWindow/Resources/MainWindow/search/main_search_deldown.png);}\
                                                QPushButton#searchBtn:hover {border-image:url(:/QQMainWindow/Resources/MainWindow/search/main_search_delhighlight.png);}\
                                                QPushButton#searchBtn:pressed{ border-image:url(:/QQMainWindow/Resources/MainWindow/search/main_search_delhighdown.png);}");
    
            }
            else if (event->type() == QEvent::FocusOut)
            {
                ui.searchWidget->setStyleSheet(QString("QWidget#searchWidget {background-color:rgba(%1,%2,%3,50);}\
                                                        QPushButton#searchBtn {border-image:url(:/QQMainWindow/Resources/MainWindow/search/search_icon.png);}").arg(m_colorBackGround.red()).arg(m_colorBackGround.green()).arg(m_colorBackGround.blue()));
            }
        }
        return __super::eventFilter(obj, event);
    }
    
    void QQMainWindow::mousePressEvent(QMouseEvent *event)
    {
        if (qApp->widgetAt(event->pos()) != ui.lineEdit && ui.lineEdit->hasFocus())
        {
            ui.lineEdit->clearFocus();
        }
        else if (qApp->widgetAt(event->pos()) != ui.searchLineEdit && ui.searchLineEdit->hasFocus())
        {
            ui.searchLineEdit->clearFocus();
        }
        __super::mousePressEvent(event);
    }
    
    void QQMainWindow::initContactTree()
    {
        //展开和收缩时信号,以达到变更我三角图片;
        connect(ui.treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(onItemClicked(QTreeWidgetItem *, int)));
        connect(ui.treeWidget, SIGNAL(itemExpanded(QTreeWidgetItem *)), this, SLOT(onItemExpanded(QTreeWidgetItem *)));
        connect(ui.treeWidget, SIGNAL(itemCollapsed(QTreeWidgetItem *)), this, SLOT(onItemCollapsed(QTreeWidgetItem *)));
        //分组节点
        QTreeWidgetItem *pRootFriendItem = new QTreeWidgetItem();
        pRootFriendItem->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);
        //设置Data用于区分,Item是分组节点还是子节点,0代表分组节点,1代表子节点
        pRootFriendItem->setData(0, Qt::UserRole, 0);
        RootContatItem *pItemName = new RootContatItem(ui.treeWidget);
    
        int nMyFriendNum = 6;
        QString qsGroupName = QString::fromLocal8Bit("我的好友 %1/%2").arg(0).arg(nMyFriendNum);
        pItemName->setText(qsGroupName);
        //擦入分组节点
        ui.treeWidget->addTopLevelItem(pRootFriendItem);
        ui.treeWidget->setItemWidget(pRootFriendItem, 0, pItemName);
    
        for (int nIndex = 0; nIndex < nMyFriendNum; ++nIndex)
        {
            //添加子节点
            addMyFriendInfo(pRootFriendItem);
        }
    }
    
    void QQMainWindow::addMyFriendInfo(QTreeWidgetItem* pRootGroupItem)
    {
        QTreeWidgetItem *pChild = new QTreeWidgetItem();
        //添加子节点
        pChild->setData(0, Qt::UserRole, 1);
        ContactItem* pContactItem = new ContactItem(ui.treeWidget);
        pContactItem->setHeadPixmap(getRoundImage(QPixmap(":/QQMainWindow/Resources/MainWindow/yutiange.jpg"), QPixmap(":/QQMainWindow/Resources/MainWindow/head_mask.png"), pContactItem->getHeadLabelSize()));
        pContactItem->setUserName(QString::fromLocal8Bit("雨田哥-工作号"));
        pContactItem->setSignName(QString::fromLocal8Bit("欢迎访问雨田哥工作号"));
        pRootGroupItem->addChild(pChild);
        ui.treeWidget->setItemWidget(pChild, 0, pContactItem);
    }
    
    void QQMainWindow::initStrangerTree()
    {
        //分组节点
        QTreeWidgetItem *pRootFriendItem = new QTreeWidgetItem();
        pRootFriendItem->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);
        //设置Data用于区分,Item是分组节点还是子节点,0代表分组节点,1代表子节点
        pRootFriendItem->setData(0, Qt::UserRole, 0);
        RootContatItem *pItemName = new RootContatItem(ui.treeWidget);
    
        int nMyFriendNum = 8;
        QString qsGroupName = QString::fromLocal8Bit("陌生人 %1/%2").arg(0).arg(nMyFriendNum);
        pItemName->setText(qsGroupName);
        //擦入分组节点
        ui.treeWidget->addTopLevelItem(pRootFriendItem);
        ui.treeWidget->setItemWidget(pRootFriendItem, 0, pItemName);
    
        for (int nIndex = 0; nIndex < nMyFriendNum; ++nIndex)
        {
            //添加子节点
            addStarngerInfo(pRootFriendItem);
        }
    }
    
    void QQMainWindow::addStarngerInfo(QTreeWidgetItem* pRootGroupItem)
    {
        QTreeWidgetItem *pChild = new QTreeWidgetItem();
        //添加子节点
        pChild->setData(0, Qt::UserRole, 1);
        ContactItem* pContactItem = new ContactItem(ui.treeWidget);
        pContactItem->setHeadPixmap(getRoundImage(QPixmap(":/QQMainWindow/Resources/MainWindow/yutiange.jpg"), QPixmap(":/QQMainWindow/Resources/MainWindow/head_mask.png"), pContactItem->getHeadLabelSize()));
        pContactItem->setUserName(QString::fromLocal8Bit("雨田哥-工作号-陌生人"));
        pContactItem->setSignName(QString::fromLocal8Bit("欢迎访问雨田哥工作号-陌生人"));
        pRootGroupItem->addChild(pChild);
        ui.treeWidget->setItemWidget(pChild, 0, pContactItem);
    }
    
    void QQMainWindow::onItemClicked(QTreeWidgetItem * item, int column)
    {
        bool bIsChild = item->data(0, Qt::UserRole).toBool();
        if (!bIsChild)
        {
            item->setExpanded(!item->isExpanded());
        }
    }
    
    void QQMainWindow::onItemExpanded(QTreeWidgetItem * item)
    {
        bool bIsChild = item->data(0, Qt::UserRole).toBool();
        if (!bIsChild)
        {
            RootContatItem *prootItem = dynamic_cast<RootContatItem*>(ui.treeWidget->itemWidget(item, 0));
            if (prootItem)
            {
                prootItem->setExpanded(true);
            }
        }
    }
    
    void QQMainWindow::onItemCollapsed(QTreeWidgetItem * item)
    {
        bool bIsChild = item->data(0, Qt::UserRole).toBool();
        if (!bIsChild)
        {
            RootContatItem *prootItem = dynamic_cast<RootContatItem*>(ui.treeWidget->itemWidget(item, 0));
            if (prootItem)
            {
                prootItem->setExpanded(false);
            }
        }
    }
    SkinWindow.cpp
    #include "skinwindow.h"
    #include "qclicklabel.h"
    #include "notifymanager.h"
    
    SkinWindow::SkinWindow(QWidget *parent)
        : BasicWindow(parent)
    {
        ui.setupUi(this);
        m_styleName = "SkinWindow";
        initControl();
        setAttribute(Qt::WA_DeleteOnClose);
        loadStyleSheet("SkinWindow");
    }
    
    SkinWindow::~SkinWindow()
    {
    
    }
    
    void SkinWindow::initControl()
    {
        QList<QColor> colorLst = { QColor(22, 154, 218), QColor(40, 138, 221), QColor(49, 166, 107), QColor(218, 67, 68),
                                   QColor(177, 99, 159), QColor(107, 81, 92), QColor(89, 92, 160), QColor(21, 156, 199) ,
                                   QColor(79, 169, 172), QColor(155, 183, 154), QColor(128, 77, 77), QColor(240, 188, 189) };
        for (int row = 0; row < 3; row++)
        {
            for (int column = 0; column < 4; column++)
            {
                QClickLabel* label = new QClickLabel(this);
                label->setCursor(Qt::PointingHandCursor);
                connect(label, &QClickLabel::clicked, [row, column, colorLst, this](){
                    NotifyManager::getInstance()->notifyOtherWindowChangeSkin(colorLst.at(4 * row + column));
                });
                label->setFixedSize(84, 84);
                QPalette palette;
                palette.setColor(QPalette::Background, colorLst.at(4 * row + column));
                label->setAutoFillBackground(true);
                label->setPalette(palette);
    
                ui.gridLayout->addWidget(label, row, column);
            }
        }
    
        connect(ui.sysmin, SIGNAL(clicked(bool)), this, SLOT(onShowMin(bool)));
        connect(ui.sysclose, SIGNAL(clicked(bool)), this, SLOT(onShowClose(bool)));
    }
    //父节点Item
    #include "rootcontatitem.h"
    #include <QPainter>
    #include <QPropertyAnimation>
    #include <QDebug>
    
    RootContatItem::RootContatItem(QWidget *parent)
        : QLabel(parent)
        , m_rotation(0)
    {
        setFixedHeight(32);
        setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
        m_animation = new QPropertyAnimation(this, "rotation");
        m_animation->setDuration(50);
        m_animation->setEasingCurve(QEasingCurve::InQuad);
    }
    
    RootContatItem::~RootContatItem()
    {
    
    }
    
    void RootContatItem::setExpanded(bool expand)
    {
        if (expand)
        {
            m_animation->setEndValue(90);
        }
        else
        {
            m_animation->setEndValue(0);
        }
        m_animation->start();
    }
    
    int RootContatItem::rotation()
    {
        return m_rotation;
    }
    
    void RootContatItem::setRotation(int rotation)
    {
        m_rotation = rotation;
        update();
    }
    
    void RootContatItem::setText(const QString& title)
    {
        m_titleText = title;
        update();
    }
    
    void RootContatItem::paintEvent(QPaintEvent *event)
    {
        QPainter painter(this);
    
        {  
            painter.setRenderHint(QPainter::TextAntialiasing, true);
            QFont font;
            font.setPointSize(10);
            painter.setFont(font);
            painter.drawText(24, 0, width() - 24, height(), Qt::AlignLeft | Qt::AlignVCenter, m_titleText);
        }
    
        {
            painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
            painter.save();
            //背景图
            QPixmap pixmap(":/QQMainWindow/Resources/MainWindow/arrow.png");
            QPixmap tmpPixmap(pixmap.size());
            tmpPixmap.fill(Qt::transparent);
    
            QPainter p(&tmpPixmap);
            p.setRenderHint(QPainter::SmoothPixmapTransform, true);
            //旋转m_rotation角度
            p.translate(pixmap.width() / 2, pixmap.height() / 2);
            p.rotate(m_rotation);
            p.drawPixmap(0 - pixmap.width() / 2, 0 - pixmap.height() / 2, pixmap);
            painter.drawPixmap(6, (height() - pixmap.height()) / 2, tmpPixmap);
            painter.restore();
        }
    
        __super::paintEvent(event);
    }
    

    结尾

    只为记录,只为分享! 愿所写能对你有所帮助。不忘记点个赞,谢谢~

    —————– 需要工程文件的,可以加我QQ —————–

    QQ等级设置效果,和好友列表展开和收缩时三角符号旋转动画效果。大家可以值得注意下。

    展开全文
  • 网页可以唤起QQ群,这我们都知道可以做到,那如何唤起呢?下面就做一个简单的介绍,希望可以帮助到有需要的朋友       ...1、官方提供的几种加群的链接 ...a 、进入该页面之后,我们登录自己的qq账号,选择要...
  • 原理: 调用UIView的三个函数:
  • 转自:http://blog.csdn.net/qq_34614629/article/details/52760957(1)Filter实现一个登陆验证的功能实现登陆成功后才能访问主页面,否则直接输入主页面的地址会自动跳转到登陆界面原理很简单,每次登陆成功后,...
  • Fragment demo仿QQ主界面

    热门讨论 2014-08-07 21:27:27
    Fragment demo仿QQ主界面,详见博客:http://blog.csdn.net/yanzi1225627/article/details/31462007#comments
  • Winform之学生信息管理系统主页面

    千次阅读 2015-04-26 13:45:51
     3我们所在主页面中添加的状态栏所显示的信息如要为我们在登录窗口输入的信息那么就需要在主页面的窗体中的构造函数做一些修改,将无参数的构造函数改为带一个字符串类型参数的构造函数,将参数传递给状态栏的属性...
  • Android开发添加QQ群 跳到QQ聊天页面

    千次阅读 2016-03-04 15:14:30
    // 此Flag可根据具体产品需要自定义,如设置,则在加群界面按返回,返回手Q界面,不设置,按返回会返回到呼起产品界面 //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) try { startActivity(intent) ; ...
  • 微信小程序-主页面静态页面搭建

    千次阅读 2018-08-31 14:07:33
    中的是页面路径,是你新建页面时自动生成进去的 "navigationBarBackgroundColor" 的取值只能使用十六进制的颜色,像 red,yellow 这样子写不生效 window 中的配置不懂去看文档去,在小程序开发==>框架==>全局配置=...
  • html页面打开QQ.exe等本地应用程序
  • 版权声明:本文为博原创文章,未经博允许不得转载。 https://blog.csdn.net/qq_33435149/article/details/86659742 其实问题是我们开启了多个Nginx的进程了,他是可以开启多个的。所以我们把开启多个的Nginx...
  • Android Fragment实现QQ界面功能

    千次阅读 2013-12-16 11:00:57
    Fragment的利用越来越多...我们可以看到,在QQ主界面的下面,有一行tab,有四个选项,可以实现切换。 新建一个项目,起名为FragmentDemoDemo。创建或者打开activity_main.xml作为程序的主布局文件,加入如下代码: <Lin
  • 在做qq登录时遇到一个情况,用户在qq的第三方的登录界面授权成功后,qq账号服务框架会打开你设置的回调页面,并将授权信息存储在hash中,由于Extjs只有一个index.html页面,其所有的视图都由js代码在index.html上...
  • 如有问题请联系QQ509961766 (一)页面布局 页面布局分为3个部分: 顶部导航:系统logo,登录信息,退出按钮等 左侧菜单:显示系统菜单 右侧展示:显示页面主要内容 (二)修改布局文件App.vue 主要...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 72,529
精华内容 29,011
关键字:

qq主页面