android:自定义viewgroup,并实现滚动条和换行

来源:互联网 发布:行李箱推荐 知乎 编辑:程序博客网 时间:2024/06/17 03:25

重点在RecipientShower#onLayout(boolean changed, int left, int top, int right, int bottom) {}



//RecipientShowHelper.java
public class RecipientShowHelper {
    int mRow;
    int mChildHeight;
    LinearLayout.LayoutParams mLayoutParams;

    public RecipientShowHelper() {

    }

    public void mesure(ViewGroup vg, int margin, boolean isLimit2Row, int viewWidth) {
        final int count = vg.getChildCount();
        mRow = 0;// which row lay you view relative to parent
        int lengthX = 0; // right position of child relative to parent
        mChildHeight = 0; // the height of child
        for (int i = 0; i < count; i++) {
            final View child = vg.getChildAt(i);
            child.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
            int width = child.getMeasuredWidth();
            mChildHeight = child.getMeasuredHeight();
            lengthX += width + margin;
            // if it can't drawing on a same line , skip to next line
            if (lengthX > viewWidth) {
                lengthX = width + margin + 0;
                mRow++;
            }
        }
        if (isLimit2Row) {
            if (mRow >= 1) {
                mLayoutParams = new LinearLayout.LayoutParams(
                        LinearLayout.LayoutParams.FILL_PARENT, (2 * mChildHeight + margin * 4));
            } else {
                mLayoutParams = new LinearLayout.LayoutParams(
                        LinearLayout.LayoutParams.FILL_PARENT, (mChildHeight + margin * 2));
            }
        }
    }

    public static void layout(int left, int top, int right, int bottom,
            ViewGroup vg, int margin) {
        final int count = vg.getChildCount();
        int row = 0;// which row lay you view relative to parent
        int lengthX = left; // right position of child relative to parent
        int lengthY = top; // bottom position of child relative to parent
        for (int i = 0; i < count; i++) {
            final View child = vg.getChildAt(i);
            int width = child.getMeasuredWidth();
            int height = child.getMeasuredHeight();
            lengthX += width + margin;
            lengthY = row * (height + margin) + margin + height + top;
            // if it can't drawing on a same line , skip to next line
            if (lengthX > right) {
                lengthX = width + margin + left;
                row++;
                lengthY = row * (height + margin) + margin + height + top;
            }
            child.layout(lengthX - width, lengthY - height, lengthX, lengthY);
        }
    }

    public int getRow() {
        return mRow;
    }

    public int getChildHeight() {
        return mChildHeight;
    }

    public LinearLayout.LayoutParams getLayoutParams() {
        return mLayoutParams;
    }

}


//RecipientShower.java

public class RecipientShower extends ViewGroup {

    private final static String TAG = "RecipientShower";

    private static final String TEL = "tel";

    private int mViewWidth = 200;

    private float mDensity = 1.0f;

    private ScrollView mScrollView;

    private Contact mContact;

    private ContactList mContactListRecipient;

    private ContactList mContactListRecipientCC;

    protected SetTheOtherRecioientEditorListener mSetTextListener;

    public static final int RECEPIENT_TYPE_NORMAL = 0;

    public static final int RECEPIENT_TYPE_RECENT = 1;

    public static final int RECEPIENT_TYPE_CC = 2;

    public final static int VIEW_MARGIN = 4;

    private int mTextView_id = -1;

    private boolean isNewCompose = true;

    private int mRow = -1;

    private int mChildHeight = -1;

    private RecipientShowHelper mShowHelper = new RecipientShowHelper();

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

    public RecipientShower(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public RecipientShower(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void initViewSize(Activity activity) {
        DisplayMetrics metric = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(metric);
        mViewWidth = metric.widthPixels - 10;
        mDensity = metric.density;
    }

    public void setViewWidth(int width) {
        this.mViewWidth = width;
    }

    public void setmScrollView(ScrollView mScrollView) {
        this.mScrollView = mScrollView;
    }

    public void setmDensity(float mDensity) {
        this.mDensity = mDensity;
    }

    public void setmContext(Context mContext) {
        this.mContext = mContext;
    }

    public void setmSetTextListener(SetTheOtherRecioientEditorListener mSetTextListener) {
        this.mSetTextListener = mSetTextListener;
    }

    public boolean isNewCompose() {
        return isNewCompose;
    }

    public void setNewCompose(boolean isNewCompose) {
        this.isNewCompose = isNewCompose;
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
    }

    public void removeAllViews() {
        super.removeAllViews();
        mContactListRecipient.clear();
        mContactListRecipientCC.clear();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (!isNewCompose) {
            getScrollLayoutParams();
        }
        setMeasuredDimension(mViewWidth, ((mRow + 1) * mChildHeight + VIEW_MARGIN * (mRow + 1) * 2));
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        RecipientShowHelper.layout(left, top, right, bottom, this, VIEW_MARGIN);
        if (mScrollView != null) {
            mScrollView.scrollTo(0, getHeight());
        }
    }

    public void addTextViewChild(int recipientType, Contact contact) {
        Paint paint = new Paint();
        String text = contact.getName();
        int background;
        int textview_id;
        if (recipientType == RECEPIENT_TYPE_NORMAL) {
            background = R.drawable.pressed_span_bg;
            mContactListRecipient.add(contact);
            textview_id = mContactListRecipient.size();
        } else {
            background = R.drawable.pressed_span_cc_bg;
            text = "CC:" + text;
            mContactListRecipientCC.add(contact);
            textview_id = mContactListRecipientCC.size() * -1;
        }
        paint.setTextSize(16.0f);
        int width = (int) (paint.measureText(text) * mDensity);
        TextView tv = new TextView(mContext);
        tv.setId(textview_id);
        tv.setTextSize(16.0f);
        tv.setText(text);
        tv.setBackgroundResource(background);
        // tv.setWidth(width);
        tv.setHeight(mContext.getResources().getDimensionPixelSize(R.dimen.span_button_height));
        tv.setSingleLine(true);
        /*
         * if (isLandscape()) { tv.setMaxWidth((int)
         * getResources().getDimension(
         * R.dimen.recipient_editor_span_width_land)); } else {
         * tv.setMaxWidth((int)
         * getResources().getDimension(R.dimen.recipient_editor_span_width_port
         * )); }
         */
        tv.setMaxWidth(mViewWidth - VIEW_MARGIN);
        tv.setClickable(true);
        tv.setOnClickListener(onClickListener);
        addView(tv);

    }

    public void reAddTextViewChild() {
        final int count = getChildCount();
        for (int index = 0; index < count; index++) {
            final View child = this.getChildAt(index);
            String text;
            int background;
            Contact contact;
            int textview_id = child.getId();
            if (textview_id > 0) {
                background = R.drawable.pressed_span_bg;
                contact = mContactListRecipient.get(textview_id - 1);
                text = contact.getName();
            } else {
                background = R.drawable.pressed_span_cc_bg;
                contact = mContactListRecipientCC.get((textview_id * -1) - 1);
                text = "CC:" + contact.getName();
            }
            TextView tv = new TextView(mContext);
            tv.setId(child.getId());
            tv.setTextSize(16.0f);
            tv.setText(text);
            tv.setBackgroundResource(background);
            tv.setHeight(mContext.getResources().getDimensionPixelSize(R.dimen.span_button_height));
            tv.setSingleLine(true);
            tv.setMaxWidth(mViewWidth - VIEW_MARGIN);
            tv.setClickable(true);
            tv.setOnClickListener(onClickListener);
            removeViewAt(index);
            addView(tv, index);
        }

    }

    public LinearLayout.LayoutParams getScrollLayoutParams() {
        mShowHelper.mesure(this, VIEW_MARGIN, isNewCompose, mViewWidth);
        mRow = mShowHelper.getRow();
        mChildHeight = mShowHelper.getChildHeight();
        return mShowHelper.getLayoutParams();
    }

    public interface SetTheOtherRecioientEditorListener {
        /**
         * before edit the number,move the old number to
         * mRecipientsEditor_Orginal.
         *
         * @param number
         */
        void setTheOtherRecipientEditorText(String number);

        /**
         * If the contact is exist in the mNotInDbRecipientCCMap or
         * mInDbRecipientCCMap on new compose message return true,else return
         * false.
         *
         * @param contact
         * @return
         */
        boolean isExistInRecipientCCMap_New_Message(Contact contact);

        /**
         * synchronized the Contactlist in RecipientsEditor.
         */
        void syncContactList(ContactList contactListRecipient, ContactList contactListRecipientCC);
    }
}

<!--布局文件-->
<ScrollView
                android:id="@+id/my_scrollview"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:fadingEdge="none">

                <com.android.mms.thundersoft.ui.RecipientShower
                    android:id="@+id/recipient_shower"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    />
             </ScrollView>