【GT-安卓应用开发之点赞列表实现】

前言:今天闲来无事想到了刚接触安卓不久的时候特别感兴趣的一个东西,那就是自定义View属性。恰巧今天闲来无事,就写一个简单的类似于朋友圈点赞列表的小程序。

        我的思路是这样的:点赞列表采用流式布局,由于用户点击名字可以查看用户资料,所以我自定义一个TextView,并定义一个展示用的username和查询资料所需要的userid。

        首先,实现自定义TextView:

        1、定义自定义属性

        在values目录下新建xml文件attrs.xml,添加代码

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyTextView">
        <attr name="username" format="string"/>
        <attr name="userid" format="integer"/>
        <attr name="style" format="string" >
            <flag name="styleA" value="0"/>
            <flag name="styleB" value="1"/>
        </attr>
        <attr name="check" format="string" >
            <flag name="checked" value="0"/>
            <flag name="unchecked" value="1"/>
        </attr>
    </declare-styleable>
</resources>

        2、创建MyTextView并继承TextView,实现构造函数和onDraw方法(onMeasure跟onLayout用不到就不需重写了)

public class MyTextView extends TextView{
    private String username;
    private int userid = -1;
    private String style;
    private String checked;

    public MyTextView(Context context) {
        super(context);
    }

    public MyTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.MyTextView);
        username = ta.getString(R.styleable.MyTextView_username);
        userid = ta.getInt(R.styleable.MyTextView_userid,-1);
        style = ta.getString(R.styleable.MyTextView_style);
        checked = ta.getString(R.styleable.MyTextView_check);
        Log.e("checked",checked+"s");
        ta.recycle();
    }

    public MyTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.MyTextView);
        username = ta.getString(R.styleable.MyTextView_username);
        userid = ta.getInt(R.styleable.MyTextView_userid,-1);
        style = ta.getString(R.styleable.MyTextView_style);
        checked = ta.getString(R.styleable.MyTextView_check);
        ta.recycle();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(style.equals("0x0")){
            setText(username+",");
        }else{
            setText(username);
        }
        if(checked.equals("0x0")){
            setTextColor(Color.BLUE);
        }else{
            setTextColor(Color.GRAY);
        }

    }
    public String getUserName(){
        return username;
    }
    public int getUserId(){
        return userid;
    }
}

        TextView创建完了,则创建流式布局(从网上找了一个直接套过来的)

public class MyFlowLayout extends ViewGroup {


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

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

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

    private List<List<View>> mLineViews = new ArrayList<List<View>>();
    private List<Integer> mLineHeight = new ArrayList<Integer>();

    /**
     * 测量所有子View大小,确定ViewGroup的宽高
     *
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        //由于onMeasure会执行多次,避免重复的计算控件个数和高度,这里需要进行清空操作
        mLineViews.clear();
        mLineHeight.clear();

        //获取测量的模式和尺寸大小
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec)-getPaddingLeft()-getPaddingRight();
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec)+getPaddingTop()+getPaddingBottom();


        //记录ViewGroup真实的测量宽高
        int viewGroupWidth = 0-getPaddingLeft()-getPaddingRight();
        int viewGroupHeight = getPaddingTop()+getPaddingBottom();

        if (widthMode == MeasureSpec.EXACTLY && heightMode == MeasureSpec.EXACTLY) {
            viewGroupWidth = widthSize;
            viewGroupHeight = heightSize;
        } else {
            //当前所占的宽高
            int currentLineWidth = 0;
            int currentLineHeight = 0;

            //用来存储每一行上的子View
            List<View> lineView = new ArrayList<View>();
            int childViewsCount = getChildCount();
            for (int i = 0; i < childViewsCount; i++) {
                View childView = getChildAt(i);
                //对子View进行测量
                measureChild(childView, widthMeasureSpec, heightMeasureSpec);
                MarginLayoutParams marginLayoutParams = (MarginLayoutParams) childView.getLayoutParams();
                int childViewWidth = childView.getMeasuredWidth() + marginLayoutParams.leftMargin + marginLayoutParams.rightMargin;
                int childViewHeight = childView.getMeasuredHeight() + marginLayoutParams.topMargin + marginLayoutParams.bottomMargin;

                if (currentLineWidth + childViewWidth > widthSize) {
                    //当前行宽+子View+左右外边距>ViewGroup的宽度,换行
                    viewGroupWidth = Math.max(currentLineWidth, widthSize);
                    viewGroupHeight += currentLineHeight;
                    //添加行高
                    mLineHeight.add(currentLineHeight);
                    //添加行对象
                    mLineViews.add(lineView);

                    //new新的一行
                    lineView = new ArrayList<View>();
                    //添加行对象里的子View
                    lineView.add(childView);
                    currentLineWidth = childViewWidth;

                } else {
                    //当前行宽+子View+左右外边距<=ViewGroup的宽度,不换行
                    currentLineWidth += childViewWidth;
                    currentLineHeight = Math.max(currentLineHeight, childViewHeight);
                    //添加行对象里的子View
                    lineView.add(childView);
                }


                if (i == childViewsCount - 1) {
                    //最后一个子View的时候
                    //添加行对象
                    mLineViews.add(lineView);
                    viewGroupWidth = Math.max(childViewWidth, viewGroupWidth);
                    viewGroupHeight += childViewHeight;
                    //添加行高
                    mLineHeight.add(currentLineHeight);

                }


            }

        }


        setMeasuredDimension(viewGroupWidth, viewGroupHeight);

    }

    /**
     * 设置ViewGroup里子View的具体位置
     *
     * @param changed
     * @param l
     * @param t
     * @param r
     * @param b
     */
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {

        int left = getPaddingLeft();
        int top = getPaddingTop();
        //一共有几行
        int lines = mLineViews.size();
        for (int i = 0; i < lines; i++) {
            //每行行高
            int lineHeight = mLineHeight.get(i);
            //行内有几个子View
            List<View> viewList = mLineViews.get(i);
            int views = viewList.size();

            for (int j = 0; j < views; j++) {
                View view = viewList.get(j);
                MarginLayoutParams marginLayoutParams = (MarginLayoutParams) view.getLayoutParams();
                int vl = left + marginLayoutParams.leftMargin;
                int vt = top + marginLayoutParams.topMargin;
                int vr = vl + view.getMeasuredWidth();
                int vb = vt + view.getMeasuredHeight();
                view.layout(vl, vt, vr, vb);
                left += view.getMeasuredWidth() + marginLayoutParams.leftMargin + marginLayoutParams.rightMargin;
            }
            left = getPaddingLeft();
            top += lineHeight;

        }


    }

    /**
     * 指定ViewGroup的LayoutParams
     *
     * @param attrs
     * @return
     */
    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new MarginLayoutParams(getContext(), attrs);
    }

}

        接下来就是在流式布局中添加MyTextView,我这里是静态添加的,可以在JAVA代码中通过addView实现动态添加,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:orientation="vertical">


    <com.example.administrator.testdemo.MyFlowLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
        <TextView
            android:layout_width="match_parent"
            android:layout_height="4dp"
            />
        <ImageView
            android:layout_width="20dp"
            android:layout_height="20dp"
            android:src="@drawable/dz1"/>
        <com.example.administrator.testdemo.MyTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            app:username="KOBE BRYANT"
            app:userid="24"
            android:text="1234"
            app:style="styleA"
            app:check="checked"
            android:onClick="click"
            />
        <com.example.administrator.testdemo.MyTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:username="LEBORN JAMES"
            app:userid="23"
            android:text="1234"
            app:style="styleA"
            app:check="checked"
            android:onClick="click"
            />
        <com.example.administrator.testdemo.MyTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:username="ALLEN IVERSON"
            app:userid="3"
            android:text="1234"
            app:style="styleA"
            app:check="checked"
            android:onClick="click"
            />
        <com.example.administrator.testdemo.MyTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:username="STEVE NASH"
            app:userid="10"
            android:text="1234"
            app:style="styleA"
            app:check="checked"
            android:onClick="click"
            />
        <com.example.administrator.testdemo.MyTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:username="VINCE CATER"
            app:userid="15"
            android:text="1234"
            app:style="styleA"
            app:check="checked"
            android:onClick="click"
            />
        <com.example.administrator.testdemo.MyTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:username="TRACY MCGRADY"
            app:userid="1"
            android:text="1234"
            app:style="styleA"
            app:check="checked"
            android:onClick="click"
            />
        <com.example.administrator.testdemo.MyTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:username="DWGHIT HOWARD"
            app:userid="12"
            android:text="1234"
            app:style="styleA"
            app:check="checked"
            android:onClick="click"
            />
        <com.example.administrator.testdemo.MyTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:username="KEVIN GANNET"
            app:userid="21"
            android:text="1234"
            app:style="styleA"
            app:check="checked"
            android:onClick="click"
            />
        <com.example.administrator.testdemo.MyTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:username="PAUL GASOL"
            app:userid="16"
            android:text="1234"
            app:style="styleB"
            app:check="checked"
            android:onClick="click"
            />

    </com.example.administrator.testdemo.MyFlowLayout>


</LinearLayout>

        最后就是事件的处理,在这个程序中只是点击显示username和userid,代码很简单

public void click(View view) {
    MyTextView mView = (MyTextView) view;
    Toast.makeText(MainActivity.this,mView.getUserName()+","+mView.getUserId(),Toast.LENGTH_SHORT).show();
}

效果图:

猜你喜欢

转载自blog.csdn.net/qq_17433217/article/details/81329455
今日推荐