@Override
  public View getView(int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
    String rich = Constants.RICH_TEXTS[position];

    // 通过迭代装饰方式构造解析器。
    IParser parser = new SmileyParser(mContext);
    parser = new ImageParser(mContext, parser);
    parser = new HyperlinkParser(mContext, parser);
    parser = new WeburlParser(mContext, parser);

    // 执行解析并返回解析文本段队列。
    ParseManager manager = new ParseManager();
    ArrayList<ParsedSegment> segments = manager.parse(parser, rich);

    // 用 Holder 模式更新列表数据。
    CustomLayout layout = null;
    ViewHolder holder = null;
    if (null == convertView) {
      layout = new CustomLayout(mContext);
      AbsListView.LayoutParams params =
          new AbsListView.LayoutParams(
              AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT);
      layout.setLayoutParams(params);
      layout.setOrientation(LinearLayout.VERTICAL);
      layout.setBackgroundResource(R.drawable.list_item_background);

      holder = new ViewHolder();
      holder.views = new ArrayList<View>();
      layout.setTag(holder);
    } else {
      layout = (CustomLayout) convertView;
      holder = (ViewHolder) convertView.getTag();
    }

    int i = 0;
    for (ParsedSegment segment : segments) {
      if (TextUtils.isEmpty(segment.text)) {
        continue;
      }

      if (MatchType.None == segment.type) {
        TextView textView = null;
        if (null == convertView) {
          textView = new TextView(mContext);
          LayoutParams p = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
          p.bottomMargin =
              mContext.getResources().getDimensionPixelSize(R.dimen.rich_element_margin);
          textView.setLayoutParams(p);
          textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);

          // 自定义 ClickableSpan 点击背景,有两种方法:
          // 1、自定义 LinkMovementMethod,重写其 onTouchEvent 方法;
          // 2、重写 TextView 的 OnTouchListener。
          // 两种方法的核心思想都是获取 touch event 事件,通过对 TextView 中的 ClickableSpan
          // 文本设置和移除 BackgroundColorSpan 来改变其点击背景。
          if (Constants.USE_CUSTOM_LINK) {
            textView.setMovementMethod(mLinkMovementMethod);
          } else {
            textView.setMovementMethod(LinkMovementMethod.getInstance());
            textView.setOnTouchListener(onTouchListener);
          }

          textView.setClickable(false);

          layout.addView(textView);
          holder.views.add(textView);
        } else {
          textView = (TextView) holder.views.get(i);
        }

        textView.setText(segment.text);

        ++i;

      } else if (MatchType.Image == segment.type) {
        ImageView imgView = null;
        if (null == convertView) {
          imgView = new ImageView(mContext);
          LayoutParams p = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
          p.bottomMargin =
              mContext.getResources().getDimensionPixelSize(R.dimen.rich_element_margin);
          imgView.setMaxHeight(
              mContext.getResources().getDimensionPixelSize(R.dimen.image_max_height));
          imgView.setLayoutParams(p);

          layout.addView(imgView);
          holder.views.add(imgView);
        } else {
          imgView = (ImageView) holder.views.get(i);
        }

        // 异步加载图片。
        mImageLoader.displayImage(
            segment.text.toString(), imgView, mOptions, mAnimateFirstListener);

        ++i;
      }
    }

    return layout;
  }