2011-08-22 32 views
2

我想在textview中从XML制作一个有序列表。这份名单将被列入小标题并且有适当的副标题。不幸的是,似乎在xml中对此的支持很小。我曾尝试在strings.xml中执行以下操作:Android中XML中的有序列表?

<ol> 
    <li> item 1\n 
    <li>sub-item1\n</li> 
    <li>sub-item2\n</li> 
    <li>item2\n</li> 
    <li>item3</li>  
</ol> 

与具有围绕每个项目醇各种排列等等等等。结果通常显示subitem2和项目2从子弹被缩进程。我一直在为此挠头。任何关于此的指导都会很棒。

回答

1
<string name="accessibility_service_instructions"> 
    1. Enable TalkBack (Settings -> Accessibility -> TalkBack). 
    \n\n2. Enable Explore-by-Touch (Settings -> Accessibility -> Explore by Touch). 
    \n\n3. Touch explore the Clock application and the home screen. 
    \n\n4. Go to the Clock application and change the time of an alarm. 
    \n\n5. Enable ClockBack (Settings -> Accessibility -> ClockBack). 
    \n\n6. Go to the Clock application and change an alarm. 
    \n\n7. Set the ringer to vibration mode and change an alarm. 
    \n\n8. Set the ringer to muted mode and change an alarm. 
</string> 
1

创建自定义标签处理类:

package com.thecitybank.myca.ui; 

import android.text.Editable; 
import android.text.Html; 
import android.text.Spanned; 
import android.text.style.BulletSpan; 
import android.text.style.LeadingMarginSpan; 
import android.util.Log; 

import org.xml.sax.XMLReader; 

import java.util.Stack; 

public class MyTagHandler implements Html.TagHandler { 
    private static final String OL_TAG = "ol"; 
    private static final String UL_TAG = "ul"; 
    private static final String LI_TAG = "li"; 


    private static final int INDENT_PX = 10; 
    private static final int LIST_ITEM_INDENT_PX = INDENT_PX * 2; 
    private static final BulletSpan BULLET_SPAN = new BulletSpan(INDENT_PX); 


    private final Stack<ListTag> lists = new Stack<ListTag>(); 


    @Override 
    public void handleTag(final boolean opening, final String tag, final Editable output, final XMLReader xmlReader) { 
     if (UL_TAG.equalsIgnoreCase(tag)) { 
      if (opening) { // handle <ul> 
       lists.push(new Ul()); 
      } else { // handle </ul> 
       lists.pop(); 
      } 
     } else if (OL_TAG.equalsIgnoreCase(tag)) { 
      if (opening) { // handle <ol> 
       lists.push(new Ol()); // use default start index of 1 
      } else { // handle </ol> 
       lists.pop(); 
      } 
     } else if (LI_TAG.equalsIgnoreCase(tag)) { 
      if (opening) { // handle <li> 
       lists.peek().openItem(output); 
      } else { // handle </li> 
       lists.peek().closeItem(output, lists.size()); 
      } 
     } else { 
      Log.d("TagHandler", "Found an unsupported tag " + tag); 
     } 
    } 

    /** 
    * Abstract super class for {@link Ul} and {@link Ol}. 
    */ 
    private abstract static class ListTag { 
     /** 
     * Opens a new list item. 
     * 
     * @param text 
     */ 
     public void openItem(final Editable text) { 
      if (text.length() > 0 && text.charAt(text.length() - 1) != '\n') { 
       text.append("\n"); 
      } 
      final int len = text.length(); 
      text.setSpan(this, len, len, Spanned.SPAN_MARK_MARK); 
     } 

     /** 
     * Closes a list item. 
     * 
     * @param text 
     * @param indentation 
     */ 
     public final void closeItem(final Editable text, final int indentation) { 
      if (text.length() > 0 && text.charAt(text.length() - 1) != '\n') { 
       text.append("\n"); 
      } 
      final Object[] replaces = getReplaces(text, indentation); 
      final int len = text.length(); 
      final ListTag listTag = getLast(text); 
      final int where = text.getSpanStart(listTag); 
      text.removeSpan(listTag); 
      if (where != len) { 
       for (Object replace : replaces) { 
        text.setSpan(replace, where, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 
       } 
      } 
     } 

     protected abstract Object[] getReplaces(final Editable text, final int indentation); 

     /** 
     * Note: This knows that the last returned object from getSpans() will be the most recently added. 
     * 
     * @see Html 
     */ 
     private ListTag getLast(final Spanned text) { 
      final ListTag[] listTags = text.getSpans(0, text.length(), ListTag.class); 
      if (listTags.length == 0) { 
       return null; 
      } 
      return listTags[listTags.length - 1]; 
     } 
    } 

    /** 
    * Class representing the unordered list ({@code <ul>}) HTML tag. 
    */ 
    private static class Ul extends ListTag { 

     @Override 
     protected Object[] getReplaces(final Editable text, final int indentation) { 
      // Nested BulletSpans increases distance between BULLET_SPAN and text, so we must prevent it. 
      int bulletMargin = INDENT_PX; 
      if (indentation > 1) { 
       bulletMargin = INDENT_PX - BULLET_SPAN.getLeadingMargin(true); 
       if (indentation > 2) { 
        // This get's more complicated when we add a LeadingMarginSpan into the same line: 
        // we have also counter it's effect to BulletSpan 
        bulletMargin -= (indentation - 2) * LIST_ITEM_INDENT_PX; 
       } 
      } 
      return new Object[]{ 
        new LeadingMarginSpan.Standard(LIST_ITEM_INDENT_PX * (indentation - 1)), 
        new BulletSpan(bulletMargin) 
      }; 
     } 
    } 

    /** 
    * Class representing the ordered list ({@code <ol>}) HTML tag. 
    */ 
    private static class Ol extends ListTag { 
     private int nextIdx; 

     /** 
     * Creates a new {@code <ul>} with start index of 1. 
     */ 
     public Ol() { 
      this(1); // default start index 
     } 

     /** 
     * Creates a new {@code <ul>} with given start index. 
     * 
     * @param startIdx 
     */ 
     public Ol(final int startIdx) { 
      this.nextIdx = startIdx; 
     } 

     @Override 
     public void openItem(final Editable text) { 
      super.openItem(text); 
      text.append(Integer.toString(nextIdx++)).append(". "); 
     } 

     @Override 
     protected Object[] getReplaces(final Editable text, final int indentation) { 
      int numberMargin = LIST_ITEM_INDENT_PX * (indentation - 1); 
      if (indentation > 2) { 
       // Same as in ordered lists: counter the effect of nested Spans 
       numberMargin -= (indentation - 2) * LIST_ITEM_INDENT_PX; 
      } 
      return new Object[]{new LeadingMarginSpan.Standard(numberMargin)}; 
     } 
    } 
} 

然后在你的string.xml像添加一个字符串:

<string name="change_password_note"><![CDATA[<ol><li>Your password should contain at least one character of a-z, A-Z and 0-9. No special character is allowed.</li> <li>Please do not use any of your last three passwords.</li> <li>Please do not enter your User ID as password.</li> <li>Password minimum of 8 and maximum of 20 characters.</li></ol>]]></string> 

现在在你的文本视图中添加文字是这样的:

txtNotesDescription.setText(Html.fromHtml(getString(R.string.change_password_note),null,new MyTagHandler())); 

这是工作对于m e,您可以使用(ul)标签使用无序列表。