牛X素材推荐之TriangleRectangleLabelView

转载请注明出处:王亟亟的大牛之路

Git上看到一个比较给力的自定义展示标签的View,分享给大家TriangleRectangleLabelView。然后根据原作者的代码我会对其中运用的一些技术点加以解释,在此在此谢谢原作者的开源精神

先贴一下运行效果:

包结构

整体实现还是很轻量级的,只有一个实现的class和attrs来处理初始化。

TriangleRectangleLabelView(作者已详细标注)

public class TriangleRectangleLabelView extends TextView {
    private static final String TAG = TriangleRectangleLabelView.class.getSimpleName();

    private static final int DEFAULT_BG_COLOR = 0xff41c7cd;
    private static final int DEFAULT_CIRCLE_COLOR = 0xffffffff;
    private static final int DEFAULT_LINE_COLOR = 0xfffb9ece;
    private static final int DEFAULT_HEIGHT = 30;//dp
    private static final int DEFAULT_WIDTH = 70;//dp
    private static final int DEFAULT_ROUND_RECT_RADIUS = 8;//px
    private static final int DEFAULT_ROUND_RECT_WIDTH = 8;//px

    private Paint mBgPaint;
    private Paint mCirclePaint;
    private Paint mLinePaint;

    private int mRoundRectWidth = DEFAULT_ROUND_RECT_WIDTH;//圆角矩形宽度
    private int mRoundRectRadius = DEFAULT_ROUND_RECT_RADIUS;//矩形圆角半径
    private int mCircleRadius = 8;//圆点半径
    private int mCircleSpaceRectangle = 16;//圆点到标签的间隔
    private int mSpaceHeight = 8;//背景上下间隔
    private int mLineWidth = 2;//竖线宽度

    private int mBgColor = DEFAULT_BG_COLOR;//背景颜色
    private int mLineColor = DEFAULT_LINE_COLOR;//竖直线颜色
    private int mCircleColor = DEFAULT_CIRCLE_COLOR;//圆点颜色

    private LINE_MODE mLineMode = LINE_MODE.MIDDLE;//竖线模式

    private boolean isShowLine = false;//是否显示竖线
    private boolean isShowCircle = true;//是否显示圆点
    private boolean isDrawRoundRect = true;//是否显示矩形圆角
    private boolean isLeft = true;//是否箭头朝左显示

    private boolean isFirstPadding = true;

    public static enum LINE_MODE {
        START, MIDDLE, END
    }

    public TriangleRectangleLabelView(Context context) {
        this(context, null);
    }

    public TriangleRectangleLabelView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TriangleRectangleLabelView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        initAttrs(attrs);
        init();
    }

    private void initAttrs(AttributeSet attrs) {
        if (attrs != null) {
            TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.TriangleRectangleLabelView);

            mBgColor = a.getColor(R.styleable.TriangleRectangleLabelView_trlvBgColor, mBgColor);
            mLineColor = a.getColor(R.styleable.TriangleRectangleLabelView_trlvLineColor, mLineColor);
            mCircleColor = a.getColor(R.styleable.TriangleRectangleLabelView_trlvCircleColor, mCircleColor);

            isLeft = a.getBoolean(R.styleable.TriangleRectangleLabelView_trlvIsLeft, isLeft);
            isShowLine = a.getBoolean(R.styleable.TriangleRectangleLabelView_trlvIsShowLine, isShowLine);
            isShowCircle = a.getBoolean(R.styleable.TriangleRectangleLabelView_trlvIsShowCircle, isShowCircle);
            isDrawRoundRect = a.getBoolean(R.styleable.TriangleRectangleLabelView_trlvIsDrawRoundRect, isDrawRoundRect);

            mCircleRadius = a.getDimensionPixelSize(R.styleable.TriangleRectangleLabelView_trlvCircleRadius, mCircleRadius);
            mCircleSpaceRectangle = a.getDimensionPixelSize(R.styleable.TriangleRectangleLabelView_trlvCircleSpaceRectangle, mCircleSpaceRectangle);
            mLineWidth = a.getDimensionPixelSize(R.styleable.TriangleRectangleLabelView_trlvLineWidth, mLineWidth);
            mRoundRectWidth = a.getDimensionPixelSize(R.styleable.TriangleRectangleLabelView_trlvRoundRectWidth, mRoundRectWidth);
            mRoundRectRadius = a.getDimensionPixelSize(R.styleable.TriangleRectangleLabelView_trlvRoundRectRadius, mRoundRectRadius);

            DisplayMetrics dm = getResources().getDisplayMetrics();
            int minHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_HEIGHT, dm);
            int minWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_WIDTH, dm);
            setMinHeight(minHeight);
            setMinWidth(minWidth);
            a.recycle();
        }
    }

    private void init() {
        mBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBgPaint.setStrokeWidth(4);
        mBgPaint.setStyle(Paint.Style.FILL);
        mBgPaint.setColor(mBgColor);
        mBgPaint.setAntiAlias(true);

        mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mCirclePaint.setStrokeWidth(1);
        mCirclePaint.setStyle(Paint.Style.FILL);
        mCirclePaint.setColor(mCircleColor);
        mCirclePaint.setAntiAlias(true);

        mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mLinePaint.setStrokeWidth(mLineWidth);
        mLinePaint.setStyle(Paint.Style.FILL);
        mLinePaint.setColor(mLineColor);
        mLinePaint.setAntiAlias(true);
    }

    /**
     * 设置圆角矩形宽度
     *
     * @param roundRectWidth px
     */
    public void setRoundRectWidth(int roundRectWidth) {
        this.mRoundRectWidth = roundRectWidth;
        postInvalidate();
    }

    /**
     * 设置圆角矩形圆角半径
     *
     * @param roundRectRadius px
     */
    public void setRoundRectRadius(int roundRectRadius) {
        this.mRoundRectRadius = roundRectRadius;
        postInvalidate();
    }

    public void setBgColor(int color) {
        mBgColor = color;
        mBgPaint.setColor(mBgColor);
        postInvalidate();
    }

    public void setLineColor(int color) {
        mLineColor = color;
        mLinePaint.setColor(getContext().getResources().getColor(mLineColor));
        postInvalidate();
    }

    /**
     * 设置竖直线模式
     *
     * @param lineMode LINE_MODE: START, MIDDLE, END
     */
    public void setLineMode(LINE_MODE lineMode) {
        this.mLineMode = lineMode;
        postInvalidate();
    }

    /**
     * 是否箭头朝向左
     *
     * @param isLeft true:left false:right
     */
    public void setLeft(boolean isLeft) {
        this.isLeft = isLeft;
        postInvalidate();
    }

    /**
     * 设置 View 上下间距
     *
     * @param spaceHeight px
     */
    public void setSpaceHeight(int spaceHeight) {
        this.mSpaceHeight = spaceHeight;
        isFirstPadding = true;
        postInvalidate();
    }

    /**
     * 设置原点与标签的间隔
     *
     * @param circleSpaceRectangle px
     */
    public void setCircleSpaceRectangle(int circleSpaceRectangle) {
        this.mCircleSpaceRectangle = circleSpaceRectangle;
        isFirstPadding = true;
        postInvalidate();
    }

    /**
     * 设置原点半径
     *
     * @param circleRadius px
     */
    public void setCircleRadius(int circleRadius) {
        this.mCircleRadius = circleRadius;
        isFirstPadding = true;
        postInvalidate();
    }

    /**
     * 设置分割线宽度
     *
     * @param lineWidth px
     */
    public void setLineWidth(int lineWidth) {
        this.mLineWidth = lineWidth;
        mLinePaint.setStrokeWidth(mLineWidth);
        postInvalidate();
    }

    public void setShowLine(boolean isShowLine) {
        this.isShowLine = isShowLine;
        postInvalidate();
    }

    public void setShowCircle(boolean isShowCircle) {
        this.isShowCircle = isShowCircle;
        postInvalidate();
    }

    public void setDrawRoundRect(boolean isDrawRoundRect) {
        this.isDrawRoundRect = isDrawRoundRect;
        postInvalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        drawBackground(canvas);
        super.onDraw(canvas);
    }

    private void drawBackground(Canvas canvas) {
        int height = getHeight();
        int width = getWidth();
        Log.d(TAG, "height = " + height);
        Log.d(TAG, "width = " + width);

        Log.d(TAG, "isFirstPadding = " + isFirstPadding);
        //-------------------Set Text Padding Begin----------------------------//
        if (isFirstPadding) {
            int paddingLeft = mCircleRadius * 2 + mCircleSpaceRectangle + (height - mSpaceHeight) / 2 + 2;
            setPadding(isLeft ? paddingLeft : mRoundRectWidth, mSpaceHeight + 4, isLeft ? mRoundRectWidth + 4 : paddingLeft, mSpaceHeight + 4);
            setGravity(Gravity.CENTER_VERTICAL);
            isFirstPadding = false;
        }
        //-------------------Set Text Padding End----------------------------//

        //-------------------Draw Line Begin----------------------------//
        int startLineX = isShowLine ? (isLeft ? mCircleRadius : width - mCircleRadius) : 0;
        if (isShowLine) {
            if (mLineMode == LINE_MODE.START) {
                canvas.drawLine(startLineX, height / 2, startLineX, height, mLinePaint);
            } else if (mLineMode == LINE_MODE.MIDDLE) {
                canvas.drawLine(startLineX, height, startLineX, 0, mLinePaint);
            } else if (mLineMode == LINE_MODE.END) {
                canvas.drawLine(startLineX, height / 2, startLineX, 0, mLinePaint);
            }
        }
        //-------------------Draw Line End----------------------------//

        //-------------------Draw Circle Begin----------------------------//
        int startCircleX = isShowCircle ? (isLeft ? mCircleRadius : width - mCircleRadius) : 0;
        if (isShowCircle) {
            canvas.drawCircle(startCircleX, height / 2, mCircleRadius, mCirclePaint);
        }
        //-------------------Draw Circle End----------------------------//

        //-------------------Draw RoundRect Begin----------------------------//
        int roundLeft = isDrawRoundRect ? (isLeft ? width - mRoundRectWidth : 0) : 0;
        int roundRight = isDrawRoundRect ? (isLeft ? width : mRoundRectWidth) : 0;

        if (isDrawRoundRect) {
            //draw RoundRect
            RectF rect = new RectF();
            rect.left = roundLeft;
            rect.top = mSpaceHeight;
            rect.right = roundRight;
            rect.bottom = height - mSpaceHeight;
            canvas.drawRoundRect(rect, mRoundRectRadius, mRoundRectRadius, mBgPaint);
        }
        //-------------------Draw RoundRect End----------------------------//

        //-------------------Draw Triangle And Rectangle Begin----------------------------//
        if (isLeft) {
            //draw Triangle And Rectangle
            int startX = mCircleSpaceRectangle + 2 * mCircleRadius;
            Point a = new Point(startX, height / 2);
            Point b = new Point(startX + (height - mSpaceHeight) / 2, height - mSpaceHeight);
            Point c = new Point(width - (isDrawRoundRect ? mRoundRectWidth / 2 : 0), height - mSpaceHeight);
            Point d = new Point(width - (isDrawRoundRect ? mRoundRectWidth / 2 : 0), mSpaceHeight);
            Point e = new Point(startX + (height - mSpaceHeight) / 2, mSpaceHeight);
            Point f = new Point(startX, height / 2);

            Path path = new Path();
            path.moveTo(a.x, a.y);
            path.lineTo(b.x, b.y);
            path.lineTo(c.x, c.y);
            path.lineTo(d.x, d.y);
            path.lineTo(e.x, e.y);
            path.lineTo(f.x, f.y);

            canvas.drawPath(path, mBgPaint);

        } else {
            //draw Triangle And Rectangle
            int startX = width - (mCircleSpaceRectangle + 2 * mCircleRadius);
            Point a = new Point(startX, height / 2);
            Point b = new Point(startX - (height - mSpaceHeight) / 2, height - mSpaceHeight);
            Point c = new Point((isDrawRoundRect ? mRoundRectWidth / 2 : 0), height - mSpaceHeight);
            Point d = new Point((isDrawRoundRect ? mRoundRectWidth / 2 : 0), mSpaceHeight);
            Point e = new Point(startX - (height - mSpaceHeight) / 2, mSpaceHeight);
            Point f = new Point(startX, height / 2);

            Path path = new Path();
            path.moveTo(a.x, a.y);
            path.lineTo(b.x, b.y);
            path.lineTo(c.x, c.y);
            path.lineTo(d.x, d.y);
            path.lineTo(e.x, e.y);
            path.lineTo(f.x, f.y);

            canvas.drawPath(path, mBgPaint);
        }
        //-------------------Draw Triangle And Rectangle End----------------------------//
    }
}

分析:

如果要设置组合标签,就是都连在一起的需要做一下操作

 ((TriangleRectangleLabelView)findViewById(R.id.trlv1)).setLineMode(TriangleRectangleLabelView.LINE_MODE.START);
        ((TriangleRectangleLabelView)findViewById(R.id.trlv2)).setLineMode(TriangleRectangleLabelView.LINE_MODE.MIDDLE);
        ((TriangleRectangleLabelView)findViewById(R.id.trlv3)).setLineMode(TriangleRectangleLabelView.LINE_MODE.MIDDLE);
        ((TriangleRectangleLabelView)findViewById(R.id.trlv4)).setLineMode(TriangleRectangleLabelView.LINE_MODE.END);

在initAttrs()方法内对标签内容进行了各种初始化,如果你的产品并不需要加以变化,可以写死,那还省蛮多代码的。

这个自定义View牛X的就是在drawBackground()方法中的画布和逻辑计算,写的还是相当缜密的。

重点提拎一下屏幕参数类DisplayMetics

这个类是干嘛的?

提供了一种关于显示的通用信息,如显示大小,分辨率和字体。

这个类怎么初始化?

DisplayMetrics metrics = new DisplayMetrics();

getWindowManager().getDefaultDisplay().getMetrics;

而我们的自定义控件使用的是 DisplayMetrics dm = getResources().getDisplayMetrics();

补充下获取的参数是以像素为单位(Pixel) ,“像素”所指的是“绝对像素”而非“相对像素”。

通过 DisplayMetrics的 toString()方法可以获取到 DisplayMetrics的大部分 fields信息,如下是在分辨率为 480x320情况下的一些输出信息:

然后就是一系列的单位了
与分辨率无关的度量单位可以解决这一问题,Android支持下列所有单位:
px(像素):屏幕上的点。
in(英寸):长度单位。
mm(毫米):长度单位。
pt(磅):1/72英寸。
dp(与密度无关的像素):一种基于屏幕密度的抽象单位。在每英寸160点的显示器上,1dp = 1px。
dip:与dp相同,多用于android/ophone示例中。
sp(与刻度无关的像素):与dp类似,但是可以根据用户的字体大小首选项进行缩放。

因为网络问题,也贴下别的 需要的文件,源码就不传了

主布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MainActivity"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    android:background="@drawable/bg">

    <labelviewdemo.wjj.com.labelviewdemo.TriangleRectangleLabelView
        android:id="@+id/trv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#fff"
        android:singleLine="true"
        android:text="Nice"
        app:trlvIsLeft="false"
        app:trlvCircleRadius="4dp"
        android:textSize="16sp"
        android:layout_marginLeft="48dp"
        android:layout_marginTop="50dp"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <labelviewdemo.wjj.com.labelviewdemo.TriangleRectangleLabelView
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#fff"
        android:singleLine="true"
        android:text="Label 1"
        android:layout_below="@id/trv_name"
        android:textSize="16sp"
        android:layout_toEndOf="@id/trv_name"
        android:layout_toRightOf="@id/trv_name"
        app:trlvIsLeft="true"
        app:trlvCircleRadius="4dp"
        app:trlvBgColor="#ff000000"
        app:trlvCircleColor="#ffffff"
        app:trlvRoundRectRadius="12dp"
        app:trlvRoundRectWidth="10dp" />

    <labelviewdemo.wjj.com.labelviewdemo.TriangleRectangleLabelView
        android:id="@+id/trlv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#fff"
        android:singleLine="true"
        android:text="标签1"
        android:textSize="16sp"
        android:layout_centerVertical="true"
        android:layout_toEndOf="@id/trv_name"
        android:layout_toRightOf="@id/trv_name"
        app:trlvIsLeft="true"
        app:trlvCircleRadius="4dp"
        app:trlvBgColor="#72ddbf"
        app:trlvCircleColor="#95e8cd"
        app:trlvIsShowLine="true" />

    <labelviewdemo.wjj.com.labelviewdemo.TriangleRectangleLabelView
        android:id="@+id/trlv2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#fff"
        android:singleLine="true"
        android:text="标签2"
        android:textSize="16sp"
        android:layout_below="@id/trlv1"
        android:layout_toEndOf="@id/trv_name"
        android:layout_toRightOf="@id/trv_name"
        app:trlvIsLeft="true"
        app:trlvCircleRadius="4dp"
        app:trlvBgColor="#a596d6"
        app:trlvCircleColor="#b6b2db"
        app:trlvIsShowLine="true" />

    <labelviewdemo.wjj.com.labelviewdemo.TriangleRectangleLabelView
        android:id="@+id/trlv3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#fff"
        android:singleLine="true"
        android:text="标签3"
        android:textSize="16sp"
        android:layout_below="@id/trlv2"
        android:layout_toEndOf="@id/trv_name"
        android:layout_toRightOf="@id/trv_name"
        app:trlvIsLeft="true"
        app:trlvCircleRadius="4dp"
        app:trlvBgColor="#efbe78"
        app:trlvCircleColor="#f1cf9e"
        app:trlvIsShowLine="true" />

    <labelviewdemo.wjj.com.labelviewdemo.TriangleRectangleLabelView
        android:id="@+id/trlv4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#fff"
        android:singleLine="true"
        android:text="标签4"
        android:textSize="16sp"
        android:layout_below="@id/trlv3"
        android:layout_toEndOf="@id/trv_name"
        android:layout_toRightOf="@id/trv_name"
        app:trlvIsLeft="true"
        app:trlvCircleRadius="4dp"
        app:trlvBgColor="#f96bbc"
        app:trlvCircleColor="#fc9dcf"
        app:trlvIsShowLine="true" />

</RelativeLayout>

MainActivity

public class MainActivity extends AppCompatActivity {

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

        ((TriangleRectangleLabelView)findViewById(R.id.trlv1)).setLineMode(TriangleRectangleLabelView.LINE_MODE.START);
        ((TriangleRectangleLabelView)findViewById(R.id.trlv2)).setLineMode(TriangleRectangleLabelView.LINE_MODE.MIDDLE);
        ((TriangleRectangleLabelView)findViewById(R.id.trlv3)).setLineMode(TriangleRectangleLabelView.LINE_MODE.MIDDLE);
        ((TriangleRectangleLabelView)findViewById(R.id.trlv4)).setLineMode(TriangleRectangleLabelView.LINE_MODE.END);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

谢谢大家

时间: 2024-10-31 20:00:06

牛X素材推荐之TriangleRectangleLabelView的相关文章

牛X素材推荐之StackOverView

转载请注明出处:王亟亟的大牛之路 给大家推荐一个高仿5.0任务管理器的自定义View,StackOverView! 实现效果: 是不是做的很像? Git地址:https://github.com/Bossyao168/StackOverView

牛X素材推荐之MaterialTextField

转载请注明出处:王亟亟的大牛之路 深度折叠简化的一个Edit,动画也比较轻盈,但是楼主不太好把控他的使用场景,因为 是一个EditText,效果倒是不错,分享给大家学习下还是OK的. 效果: 载入包: compile 'com.github.florent37:materialtextfield:1.0.1@aar' compile 'com.android.support:cardview-v7:22.2.1' compile 'com.nineoldandroids:library:2.4.

牛X素材推荐之BannerTime

转载请注明出处王亟亟的大牛之路 平时我们会遇到各种各样的小广告推送形式今天上一个实现比较典型的自定义View,不过很值得称道的是作者对封装和代码解耦的理解. 效果图: 一个延迟弹出自定义对话框并实现其逻辑的一个自定义控件. 项目结构: 代码相当轻量级,用起来也很方便. MainActivity: public class MainActivity extends AppCompatActivity { private Context mContext = this; @Override prot

五分钟用手机拍证件照 四款超牛拍照软件推荐

拍摄证件照的要求很高,需要清晰的露出五官,背景要干净整洁,并只能采用纯色,光线明亮又不能刺眼,通常这类照片需要到专业的照相馆去拍摄,我们在家是无法完成的.证件照除了可用于一些证明身份的证件上,办理报名.入职,或投递简历也是需要的,如果此时恰好没有携带 电子版照片,而附近又没有合适的照相馆该怎么办呢?今天小编就教您如何用手机拍摄出完美的证件照,虽然不能和专业照相馆相比拟,但至少可以应急.在拍摄之前,咱们还要对环境进行一下布置,最好是一整面白色的墙壁,如果实在找不到,只要不是太杂乱也可以.一般家里都

WPS Office抢鲜版V8.0发布 素材库速度提升5倍

日前,金山办公软件正式发布了WPS Office抢鲜版V8.0,该版本新品秉承了WPS Office 2012灵巧轻快.便捷安装,深度兼容微软Office的特点,可以轻松在时尚界面与经典界面之间一键切换.另外,WPS Office 抢鲜版V8.0对在线素材库进行了改进,使素材库的速度较之前提升5倍,同时段落布局的使用也更加方便,还支持页面颜色的更换,颜色.纹理.图案想怎么来就怎么来,让用户的办公操作更加简单轻松. 网友可登陆WPS官网(http://www.wps.cn/product/beta

《我叫MT online》物抗卡牌推荐

物抗卡牌是指那些非常禁打,可以当做肉盾, 生命值非常高的卡牌,一般物抗卡牌的职业都是战士,最大生命值可达几万,但是攻击很小.下面给大家推荐几张物抗卡牌::哀木涕+3职业:战士星级:5领导力:28最大生命:49468最大攻击:5072出处:哀木涕进化入手难度:★ 前期推荐星级:★★ 后期推荐星级:★★★☆ PVP推荐星级:★★ PVE推荐星级:★★☆一句话推荐:无疑哀木涕进化到最大等级,是无敌一般的存在,起码在当前版本 血量是相当的可观.对于哀木涕这种纯坦克,伤害低到一定程度也是可以理解的.:桶牛

15款新鲜出炉的实用网页设计工具

  在信息爆炸的今天,设计师要通过网络寻找设计素材 和工具是一件简单的事情,相应的,要找到真正可靠且素质优秀的素材 ,也越发的不容易.在海量的网站中寻找一个符合需求的素材 ,花费在搜索和筛选上的时间也越来越长.这种情况使得今天这样的设计工具/素材推荐类的文章与合集显得更有意义,也弥足珍贵. 由于网页设计师和开发者之间的界限越来越模糊,两者所用的工具和素材的交叉重叠的情况也非常普遍.今天所推荐的这15项全新的工具/素材里,应该有很多都值得网页设计从业者们收入囊中.这当中涵盖了设计类应用.框架.分析

从《我是歌手》学习淘宝运营

原文地址:http://www.xinli001.com/info/4654/ 我们生活在互联网的圈子里,经常会认为自己做的事情很牛,其实相对传统行业,我们还太小.电商发展够快吧?但网络零售总额才占线下零售总额的5%左右.电商发展才10来年,而很多传统行业发展好几十年,甚至上百年,我们更应该向他们学习,本质都一样,只是环境不同.今天我跟大家谈谈如何从电视节目学习电商运营. 说到电视节目,除了CCAV,估计就是湖南卫视芒果台了.目前最火的节目也莫过于芒果台的<我是歌手>.如果你没看过一定要去看看

关于数据的笑话 30 则

1.[做数据分析的好处]记者:不怕你老公在外面乱来吗?媳妇:他是数据分析师:记者:你不在身边不怕他空虚寂寞么>媳妇:他要整数据.记者:那他 会不会花心变坏?媳妇:不会,他很忙,要每天要改分析报告.记者:你觉得这样好吗?媳妇:很好!玩数据就没钱玩女人!有点钱都换电脑去了. 2.[厕所才是精准定向投放广告的好地?]张栋:我发现我是个喜欢看广告的人,公司楼层的男厕所里经常是游戏,贷款公司还有 SPA 会所等广告.我好奇女厕所里贴什么广告.今天找了个女工程师帮我进去看了一下:广告是一样的!看来没做(性别