Android 图文混排

先上图,看下实现效果
这里写图片描述
这里实现的是左上角是图片,右边和下边是文本内容,下边内容为上边内容的换行现实,这里的标题行数是可控的,如果只是一行的话获取很多人说用SpannableString就可以实现,但是有个问题,SpannableString可以替换添加图片,可以添加背景颜色,但是SpannableString是否可以添加背景图片呢,举个例子,我标题前两个字是“新闻”,我想给新闻添加一个图片背景,这样用SpannableString 就无法实现了,这里给大家介绍一种简单的方法,具体想要实现别的特殊效果可以根据需求自行去修改。

实现思路:
1、上半部分是ImageView和TextView(标题),下半部分是TextView(内容)
2、先设置图片,然后再设是标题TextView,设置之后根本TextView可显示的长度,判断剩下的内容再设置内容TextView的显示内容

这里将自定义一个LinearLayout,用于显示整体内容,这里先看下布局文件

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

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <ImageView
                android:id="@+id/iamgeview"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@mipmap/ic_launcher"/>

            <com.xxx.MyTextView
                android:id="@+id/text_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:lines="2"
                android:textSize="20sp" />
        </LinearLayout>

        <TextView
            android:id="@+id/textview_buttom"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="18sp" />
</LinearLayout>

自定义布局里面用到了一个MyTextView,这是一个自定义的TextView,主要是用于获取TextView设置显示内容之后View的宽高,具体代码如下:

public class MyTextView extends TextView {

    public MyTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }

    public MyTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    public MyTextView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    SizeChangeListener l;

    /** 设置接收的接口*/
    public void setSizeChangeListener(SizeChangeListener orlExt) {
        l = orlExt;
    }

    @Override
    public void onSizeChanged(int w, int h, int oldw, int oldh) {
        // TODO Auto-generated method stub
        l.sizeChanged(w, h, oldw, oldh);
        super.onSizeChanged(w, h, oldw, oldh);
    }

    /** 定义接收的接口*/
    public interface SizeChangeListener {
        public void sizeChanged(int w, int h, int oldw, int oldh);
    }
}

上述MyTextView内容不多,也挺好理解的,主要是想获取TextView设置Text之后的宽高,这样用于下面得计算。具体View内容如下:

public class MyDetailView extends LinearLayout {

    /** 标题行数*/
    private int TITLE_LINES = 1;
    private MyTextView myTextView;
    private TextView textViewButtom;
    private ImageView imageView;
    String text = "";

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

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

    public MyDetailView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        LayoutInflater.from(context).inflate(R.layout.test,this,true);
        initView();
    }

    private void initView(){
        myTextView = (MyTextView) findViewById(R.id.text_title);
        textViewButtom = (TextView) findViewById(R.id.textview_buttom);
        imageView = (ImageView) findViewById(R.id.iamgeview);

    }

    /** 设置文本显示内容*/
    public void setText(String text){
        this.text = text;
        myTextView.setText(text);
        setView();
    }

    /** 设置标题显示行数*/
    public void setTitleLines(int lines){
        TITLE_LINES = lines;
        setView();
    }

    /** 设置内容*/
    private void setView(){
        myTextView.setSizeChangeListener(new MyTextView.SizeChangeListener() {
            @Override
            public void sizeChanged(int w, int h, int oldw, int oldh) {
                Log.e("--",w+"  "+h+"  "+oldw+"  "+oldh+"  ");
                int sumWidth = 0;
                for (int index=0; index<text.length(); index++) {
                    // 计算每一个字符的宽度
                    char c = text.charAt(index);
                    float charWidth = getCharWidth(myTextView, c);
                    sumWidth += charWidth;
                    //如果一行显示不了 则底部textview显示剩余内容
                    if(sumWidth >= w * TITLE_LINES){
                        String remain = text.substring(index);
                        textViewButtom.setText(remain+"");
                        return;
                    }
                }
            }
        });
    }

    /** 计算每一个字符的宽度*/
    public float getCharWidth(TextView textView, char c) {
        TextPaint textPaint = textView.getPaint();
        float textPaintWidth = textPaint.measureText(String.valueOf(c));
        return textPaintWidth;
    }
}

上述代码都有注释,想要调用的时候直接在布局文件里面调用即可

<com.xx.MyDetailView
        android:id="@+id/my_detail_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"></com.wx.clonewx.MyDetailView>

MyDetailView myDetailView = (MyDetailView) findViewById(R.id.my_detail_view);
        myDetailView.setText("11月30日,北京电视台大楼在雾霾中若隐若现。当日,北京现空气重污染过程,这是自今年3月31日《北京市空气重污染应急预案》修订后,首次启动橙色级别的预警,也是今年首个空气重污染橙色预警。");

用的同学可以根据自己需求更改,可是对图片设置,或者对布局进行设置,这里只是提供一个思路。有疑问可以留言,交流讨论。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值