欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android仿微信朋友圈全文、收起功能的实例代码

程序员文章站 2023-12-01 18:25:04
前言 一般在社交app中都有类似朋友圈的功能,其中发表的动态内容很长的时候不可能让它全部显示。这里就需要做一个仿微信朋友圈全文、收起功能来解决该问题。在网上看到一个例子-...

前言

一般在社交app中都有类似朋友圈的功能,其中发表的动态内容很长的时候不可能让它全部显示。这里就需要做一个仿微信朋友圈全文、收起功能来解决该问题。在网上看到一个例子-->,写的很不错,但是有个bug,他这个demo只有在条目固定的时候才正常,当增加、删除条目的时候会出现全文、收起显示混乱的问题。原因是他使用了固定的position作为key来保存当前显示的状态。这篇文章在他的基础上进行优化。

效果图

Android仿微信朋友圈全文、收起功能的实例代码

具体代码

(详细解释在代码注释中都有,这里就省略了)

mainactivity.java

package com.wildma.wildmaexpandfoldtext;

import android.os.bundle;
import android.support.v7.app.appcompatactivity;
import android.support.v7.widget.linearlayoutmanager;
import android.support.v7.widget.recyclerview;

import java.util.arraylist;
import java.util.list;

/**
 * author   wildma
 * date    2017/8/3
 * des    ${todo}
 */
public class mainactivity extends appcompatactivity {
  private recyclerview mrecyclerview;
  list<expandfoldtextbean> mlist = new arraylist<>();

  @override
  protected void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.activity_main);

    initdata();
    expandfoldtextadapter adapter = new expandfoldtextadapter(mlist, this);
    mrecyclerview = (recyclerview) findviewbyid(r.id.recyclerview);
    mrecyclerview.setlayoutmanager(new linearlayoutmanager(this, linearlayoutmanager.vertical, false));
    mrecyclerview.setadapter(adapter);
  }

  /**
   * 初始化数据
   */
  private void initdata() {
    string longcontent = "-->游泳、快走、慢跑、骑自行车,及一切有氧运动都能锻炼心脏。有氧运动好处多:能锻炼心肺、增强循环系统功能、燃烧脂肪、加大肺活量、降低血压,甚至能预防糖尿病,减少心脏病的发生。美国运动医学院建议,想知道有氧运动强度是否合适,可在运动后测试心率,以达到最高心率的60%—90%为宜。如果想通过有氧运动来减肥,可以选择低度到中度的运动强度,同时延长运动时间,这种方法消耗的热量更多。运动频率每周3—5次,每次20—60分钟。想要锻炼肌肉,可以练举重、做体操以及其他重复伸、屈肌肉的运动。肌肉锻炼可以燃烧热量、增强骨密度、减少受伤,尤其是关节受伤的几率,还能预防骨质疏松。 在做举重运动前,先测一下,如果连续举8次你最多能举多重的东西,就从这个重量开始练习。当你可以连续12次举起这个重量时,试试增加5%的重量。注意每次练习时,要连续举8—12次,这样可以达到肌肉最大耐力的70%—80%,锻炼效果较好。每周2—3次,但要避免连续两天锻炼同一组肌肉群, 以便让肌肉有充分的恢复时间。";
    string shortcontent = "-->健身是一种体育项目,如各种徒手健美操、韵律操、形体操以及各种自抗力动作。";
    for (int i = 0; i < 20; i++) {
      expandfoldtextbean bean = new expandfoldtextbean();
      if (i % 2 == 0) {
        bean.setcontent(i + shortcontent);
        bean.setid(i);
      } else {
        bean.setcontent(i + longcontent);
        bean.setid(i);
      }
      mlist.add(bean);
    }
  }
}

expandfoldtextadapter.java

package com.wildma.wildmaexpandfoldtext;

import android.app.activity;
import android.support.v7.widget.recyclerview;
import android.util.sparsearray;
import android.view.view;
import android.view.viewgroup;
import android.view.viewtreeobserver;
import android.widget.textview;

import java.util.list;

/**
 * author   wildma
 * date    2017/8/3
 * des    ${展开折叠文本适配器}
 */
public class expandfoldtextadapter extends recyclerview.adapter<expandfoldtextadapter.myviewholder> {
  private activity mcontent;

  private final int max_line_count = 3;//最大显示行数

  private final int state_unknow = -1;//未知状态

  private final int state_not_overflow = 1;//文本行数小于最大可显示行数

  private final int state_collapsed = 2;//折叠状态

  private final int state_expanded = 3;//展开状态

  /**
   * 注意:保存文本状态集合的key一定要是唯一的,如果用position。
   * 如果使用position作为key,则删除、增加条目的时候会出现显示错乱
   */
  private sparsearray<integer> mtextstatelist;//保存文本状态集合

  list<expandfoldtextbean> mlist;

  public expandfoldtextadapter(list<expandfoldtextbean> list, activity context) {
    mcontent = context;
    this.mlist = list;
    mtextstatelist = new sparsearray<>();
  }

  @override
  public myviewholder oncreateviewholder(viewgroup parent, int viewtype) {
    return new myviewholder(mcontent.getlayoutinflater().inflate(r.layout.item_expand_fold_text, parent, false));
  }

  @override
  public void onbindviewholder(final myviewholder holder, final int position) {
    int state = mtextstatelist.get(mlist.get(position).getid(), state_unknow);
    //第一次初始化,未知状态
    if (state == state_unknow) {
      holder.content.getviewtreeobserver().addonpredrawlistener(new viewtreeobserver.onpredrawlistener() {
        @override
        public boolean onpredraw() {
          //这个回掉会调用多次,获取完行数后记得注销监听
          holder.content.getviewtreeobserver().removeonpredrawlistener(this);
          //holder.content.getviewtreeobserver().addonpredrawlistener(null);
          //如果内容显示的行数大于最大显示行数
          if (holder.content.getlinecount() > max_line_count) {
            holder.content.setmaxlines(max_line_count);//设置最大显示行数
            holder.expandorfold.setvisibility(view.visible);//显示“全文”
            holder.expandorfold.settext("全文");
            mtextstatelist.put(mlist.get(position).getid(), state_collapsed);//保存状态
          } else {
            holder.expandorfold.setvisibility(view.gone);
            mtextstatelist.put(mlist.get(position).getid(), state_not_overflow);
          }
          return true;
        }
      });

      holder.content.setmaxlines(integer.max_value);//设置文本的最大行数,为整数的最大数值
      holder.content.settext(mlist.get(position).getcontent());
    } else {
      //如果之前已经初始化过了,则使用保存的状态。
      switch (state) {
        case state_not_overflow:
          holder.expandorfold.setvisibility(view.gone);
          break;
        case state_collapsed:
          holder.content.setmaxlines(max_line_count);
          holder.expandorfold.setvisibility(view.visible);
          holder.expandorfold.settext("全文");
          break;
        case state_expanded:
          holder.content.setmaxlines(integer.max_value);
          holder.expandorfold.setvisibility(view.visible);
          holder.expandorfold.settext("收起");
          break;
      }
      holder.content.settext(mlist.get(position).getcontent());
    }

    //全文和收起的点击事件
    holder.expandorfold.setonclicklistener(new view.onclicklistener() {
      @override
      public void onclick(view v) {
        int state = mtextstatelist.get(mlist.get(position).getid(), state_unknow);
        if (state == state_collapsed) {
          holder.content.setmaxlines(integer.max_value);
          holder.expandorfold.settext("收起");
          mtextstatelist.put(mlist.get(position).getid(), state_expanded);
        } else if (state == state_expanded) {
          holder.content.setmaxlines(max_line_count);
          holder.expandorfold.settext("全文");
          mtextstatelist.put(mlist.get(position).getid(), state_collapsed);
        }
      }
    });

    //删除点击事件
    holder.delete.setonclicklistener(new view.onclicklistener() {
      @override
      public void onclick(view view) {
        mlist.remove(position);
        notifydatasetchanged();
      }
    });
  }

  @override
  public int getitemcount() {
    return mlist.size();
  }


  public class myviewholder extends recyclerview.viewholder {
    public textview nickname;
    public textview content;
    public textview delete;
    public textview expandorfold;

    public myviewholder(view itemview) {
      super(itemview);
      nickname = (textview) itemview.findviewbyid(r.id.tv_nickname);
      content = (textview) itemview.findviewbyid(r.id.tv_content);
      delete = (textview) itemview.findviewbyid(r.id.tv_delete);
      expandorfold = (textview) itemview.findviewbyid(r.id.tv_expand_or_fold);
    }
  }
}

expandfoldtextbean.java

package com.wildma.wildmaexpandfoldtext;

/**
 * author   wildma
 * date    2017/8/3
 * des    ${todo}
 */
public class expandfoldtextbean {

  private string content;//内容

  private int id;//该条数据的id

  public string getcontent() {
    return content;
  }

  public void setcontent(string content) {
    this.content = content;
  }

  public int getid() {
    return id;
  }

  public void setid(int id) {
    this.id = id;
  }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<relativelayout
  android:id="@+id/activity_main"
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:paddingbottom="@dimen/activity_vertical_margin"
  android:paddingleft="@dimen/activity_horizontal_margin"
  android:paddingright="@dimen/activity_horizontal_margin"
  android:paddingtop="@dimen/activity_vertical_margin">

  <android.support.v7.widget.recyclerview
    android:id="@+id/recyclerview"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
  </android.support.v7.widget.recyclerview>

</relativelayout>

item_expand_fold_text.xml

<?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="wrap_content"
       android:orientation="vertical"
       android:paddingbottom="@dimen/activity_vertical_margin"
       android:paddingleft="@dimen/activity_horizontal_margin"
       android:paddingright="@dimen/activity_horizontal_margin"
       android:paddingtop="@dimen/activity_vertical_margin">

  <linearlayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center_vertical"
    android:orientation="horizontal">

    <imageview
      android:layout_width="40dp"
      android:layout_height="40dp"
      android:layout_marginright="16dp"
      android:gravity="center"
      android:scaletype="centercrop"
      android:src="@mipmap/ic_launcher"/>

    <relativelayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content">

      <textview
        android:id="@+id/tv_nickname"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="wildma"
        android:textcolor="@android:color/black"
        android:textsize="14sp"/>

      <textview
        android:id="@+id/tv_delete"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignparentright="true"
        android:layout_marginleft="12dp"
        android:paddingleft="5dp"
        android:paddingright="5dp"
        android:text="删除"
        android:textcolor="@android:color/holo_red_dark"
        android:textsize="14sp"/>
    </relativelayout>

  </linearlayout>

  <linearlayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginleft="56dp"
    android:orientation="vertical"
    android:paddingbottom="8dp">

    <textview
      android:id="@+id/tv_content"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginbottom="8dp"
      android:alpha="0.85"
      android:ellipsize="end"
      android:text="内容"
      android:textcolor="@android:color/black"
      android:textsize="14sp"/>

    <textview
      android:id="@+id/tv_expand_or_fold"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="全文"
      android:textcolor="@color/colorprimarydark"
      android:textsize="14sp"/>
  </linearlayout>

  <view
    android:layout_width="match_parent"
    android:layout_height="0.5dp"
    android:background="@android:color/black"/>
</linearlayout>

源码地址:https://github.com/wildma/wildmaexpandfoldtext

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。