jjzjj

android - 类似功能 Android 的 TreeView

coder 2023-12-28 原文

我正在为我的应用程序实现 TreeView。 我在网上搜索了一下,发现一个ListView 实现TreeView 太乱了。是否可以使用 ExpandableListView 实现 n 级 TreeView

请分享您的想法或引用一些示例。

提前致谢。

最佳答案

很久以前我就用 ListView 解决了我的问题。有人遇到了同样的问题并要求我分享我的解决方案,所以我来了。

TreeElementI.java :

public interface TreeElementI extends Serializable{
  public void addChild(TreeElementI child);
  public String getId();
  public void setId(String id);
  public String getOutlineTitle();
  public void setOutlineTitle(String outlineTitle);
  public boolean isHasParent();
  public void setHasParent(boolean hasParent);
  public boolean isHasChild();
  public void setHasChild(boolean hasChild);
  public int getLevel();
  public void setLevel(int level);
  public boolean isExpanded();
  public void setExpanded(boolean expanded);
  public ArrayList<TreeElementI> getChildList();
  public TreeElementI getParent();
  public void setParent(TreeElementI parent);
}

树元素.java :

public class TreeElement implements TreeElementI{
private String id;
private String outlineTitle;
private boolean hasParent;
private boolean hasChild;
private TreeElementI parent;
private int level;
private ArrayList<TreeElementI> childList;
private boolean expanded;

public TreeElement(String id, String outlineTitle) {
    super();
    this.childList = new ArrayList<TreeElementI>();
    this.id = id;
    this.outlineTitle = outlineTitle;
    this.level = 0;
    this.hasParent = true;
    this.hasChild = false;
    this.parent = null;
}

public TreeElement(String id, String outlineTitle, boolean hasParent, boolean hasChild, TreeElement parent, int level, boolean expanded) {
    super();
    this.childList = new ArrayList<TreeElementI>();
    this.id = id;
    this.outlineTitle = outlineTitle;
    this.hasParent = hasParent;
    this.hasChild = hasChild;
    this.parent = parent;
    if(parent != null) {
        this.parent.getChildList().add(this);
    }
    this.level = level;
    this.expanded = expanded;
}

@Override
public void addChild(TreeElementI child) {
    this.getChildList().add(child);
    this.setHasParent(false);
    this.setHasChild(true);
    child.setParent(this);
    child.setLevel(this.getLevel() + 1);
}

@Override
public String getId() {
    return this.id;
}

@Override
public void setId(String id) {
    this.id = id;
}

@Override
public String getOutlineTitle() {
    return this.outlineTitle;
}

@Override
public void setOutlineTitle(String outlineTitle) {
    this.outlineTitle = outlineTitle;
}

@Override
public boolean isHasParent() {
    return this.hasParent;
}

@Override
public void setHasParent(boolean hasParent) {
    this.hasParent = hasParent;
}

@Override
public boolean isHasChild() {
    return this.hasChild;
}

@Override
public void setHasChild(boolean hasChild) {
    this.hasChild = hasChild;
}

@Override
public int getLevel() {
    return this.level;
}

@Override
public void setLevel(int level) {
    this.level = level;
}

@Override
public boolean isExpanded() {
    return this.expanded;
}

@Override
public void setExpanded(boolean expanded) {
    this.expanded = expanded;
}

@Override
public ArrayList<TreeElementI> getChildList() {
    return this.childList;
}

@Override
public TreeElementI getParent() {
    return this.parent;
}

@Override
public void setParent(TreeElementI parent) {
    this.parent = parent;
}
}

TreeViewClassifAdapter.java :

public class TreeViewClassifAdapter extends BaseAdapter {
private static final int TREE_ELEMENT_PADDING_VAL = 25;
private List<TreeElementI> fileList;
private Context context;
private Bitmap iconCollapse;
private Bitmap iconExpand;
private Dialog dialog;
private EditText textLabel;
private XTreeViewClassif treeView;

public TreeViewClassifAdapter(Context context, List<TreeElementI> fileList, Dialog dialog, EditText textLabel, XTreeViewClassif treeView) {
    this.context = context;
    this.fileList = fileList;
    this.dialog = dialog;
    this.textLabel = textLabel;
    this.treeView = treeView;
    iconCollapse = BitmapFactory.decodeResource(context.getResources(), R.drawable.x_treeview_outline_list_collapse);
    iconExpand = BitmapFactory.decodeResource(context.getResources(), R.drawable.x_treeview_outline_list_expand);
}

public List<TreeElementI> getListData() {
    return this.fileList;
}

@Override
public int getCount() {
    return this.fileList.size();
}

@Override
public Object getItem(int position) {
    return this.fileList.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;

    convertView = View.inflate(context, R.layout.x_treeview_classif_list_item, null);
    holder = new ViewHolder();
    holder.setTextView((TextView) convertView.findViewById(R.id.text));
    holder.setImageView((ImageView) convertView.findViewById(R.id.icon));
    convertView.setTag(holder);

    final TreeElementI elem = (TreeElementI) getItem(position);

    int level = elem.getLevel();
    holder.getIcon().setPadding(TREE_ELEMENT_PADDING_VAL * (level + 1), holder.icon.getPaddingTop(), 0, holder.icon.getPaddingBottom());
    holder.getText().setText(elem.getOutlineTitle());
    if (elem.isHasChild() && (elem.isExpanded() == false)) {
        holder.getIcon().setImageBitmap(iconCollapse);
    } else if (elem.isHasChild() && (elem.isExpanded() == true)) {
        holder.getIcon().setImageBitmap(iconExpand);
    } else if (!elem.isHasChild()) {
        holder.getIcon().setImageBitmap(iconCollapse);
        holder.getIcon().setVisibility(View.INVISIBLE);
    }

    IconClickListener iconListener = new IconClickListener(this, position);
    TextClickListener txtListener = new TextClickListener((ArrayList<TreeElementI>) this.getListData(), position);
    holder.getIcon().setOnClickListener(iconListener);
    holder.getText().setOnClickListener(txtListener);
    return convertView;
}

private class ViewHolder {
    ImageView icon;
    TextView text;

    public TextView getText() {
        return this.text;
    }

    public void setTextView(TextView text) {
        this.text = text;
    }

    public ImageView getIcon() {
        return this.icon;
    }

    public void setImageView(ImageView icon) {
        this.icon = icon;
    }
}

/**
 * Listener For TreeElement Text Click
 */
private class TextClickListener implements View.OnClickListener {
    private ArrayList<TreeElementI> list;
    private int position;

    public TextClickListener(ArrayList<TreeElementI> list, int position) {
        this.list = list;
        this.position = position;
    }

    @Override
    public void onClick(View v) {
        treeView.setXValue(String.valueOf(list.get(position).getId()));
        dialog.dismiss();
    }
}

/**
 * Listener for TreeElement "Expand" button Click
 */
private class IconClickListener implements View.OnClickListener {
    private ArrayList<TreeElementI> list;
    private TreeViewClassifAdapter adapter;
    private int position;

    public IconClickListener(TreeViewClassifAdapter adapter, int position) {
        this.list = (ArrayList<TreeElementI>) adapter.getListData();
        this.adapter = adapter;
        this.position = position;
    }

    @Override
    public void onClick(View v) {
        if (!list.get(position).isHasChild()) {
            return;
        }

        if (list.get(position).isExpanded()) {
            list.get(position).setExpanded(false);
            TreeElementI element = list.get(position);
            ArrayList<TreeElementI> temp = new ArrayList<TreeElementI>();

            for (int i = position + 1; i < list.size(); i++) {
                if (element.getLevel() >= list.get(i).getLevel()) {
                    break;
                }
                temp.add(list.get(i));
            }
            list.removeAll(temp);
            adapter.notifyDataSetChanged();
        } else {
            TreeElementI obj = list.get(position);
            obj.setExpanded(true);
            int level = obj.getLevel();
            int nextLevel = level + 1;

            for (TreeElementI element : obj.getChildList()) {
                element.setLevel(nextLevel);
                element.setExpanded(false);
                list.add(position + 1, element);
            }
            adapter.notifyDataSetChanged();
        }
    }
}
}

关于android - 类似功能 Android 的 TreeView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18698376/

有关android - 类似功能 Android 的 TreeView的更多相关文章

  1. ruby-on-rails - Cucumber 是否只是 rspec 的包装器以帮助将测试组织成功能? - 2

    只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您

  2. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  3. ruby - Ruby 是否有类似于 Perl 的 "perl -d"的逐步调试器? - 2

    Ruby是否有逐步调试器,类似于Perl的“perl-d”? 最佳答案 ruby-debug(对于ruby1.8),debugger(对于ruby1.9),byebug(对于ruby​​2.0)以及trepanning系列都有一个-x或--trace选项。在调试器内部,命令setlinetrace将打开或关闭线路跟踪。这是themanualforruby-debug原来的答案已经修改,因为数据噪声文章的链接,唉,不再有效了。还添加了ruby​​-debug的后继者 关于ruby-Ruby

  4. ruby - 使对象的行为类似于 ruby​​ 中并行分配的数组 - 2

    假设您在Ruby中执行此操作:ar=[1,2]x,y=ar然后,x==1和y==2。是否有一种方法可以在我自己的类中定义,从而产生相同的效果?例如rb=AllYourCode.newx,y=rb到目前为止,对于这样的赋值,我所能做的就是使x==rb和y=nil。Python有这样一个特性:>>>classFoo:...def__iter__(self):...returniter([1,2])...>>>x,y=Foo()>>>x1>>>y2 最佳答案 是的。定义#to_ary。这将使您的对象被视为要分配的数组。irb>o=Obje

  5. 语法类似于 GitHub Flavored Markdown 的 Ruby markdown 解释器? - 2

    我使用Jekyll运行博客,并认为我会解决RedcarpetMarkdown解释器,因为它是developedandusedbyGitHub.好吧,我只是碰巧遇到了一个错误,去检查问题,然后foundthis.Maintainersays,"Asyouprobablyhavenoticed(harharharhar)Idon'thavetimetomaintainRedcarpetanymore.It'snotapriorityforme(IfindMarkdownthoroughlyboring)andit'snotapriorityforGitHub,becausewenolong

  6. ruby - Dropbox 类似 git 的服务——没有 rsync 和 inotify - 2

    关于如何使用git设置类似Dropbox的服务,您有什么建议吗?您认为git是解决此问题的合适工具吗?我在考虑使用git+rush解决方案,你觉得怎么样? 最佳答案 检查这个开源项目:https://github.com/hbons/SparkleShare来自项目的自述文件:Howdoesitwork?SparkleSharecreatesaspecialfolderonyourcomputer.Youcanaddremotelyhostedfolders(or"projects")tothisfolder.Theseprojec

  7. ruby-on-rails - rails 功能测试 - 2

    在Rails自动生成的功能测试(test/functional/products_controller_test.rb)中,我看到以下代码:classProductsControllerTest我的问题是:方法调用products()在哪里/如何定义?products(:one)到底是什么意思?看代码,大概意思是“创建一个产品”,但是它是如何工作的呢?注意我是Ruby/Rails的新手,如果这些是微不足道的问题,我深表歉意。 最佳答案 如果您查看test/fixtures文件夹,您会看到一个products.yml文件。这是在您创建

  8. python - python中有没有类似于ruby的||=的表达式 - 2

    我在Ruby中遇到了一个有趣的表达式:a||="new"表示如果没有定义a,则将"new"值赋给a;否则,a将保持原样。在进行一些数据库查询时很有用。如果设置了该值,我不想触发另一个数据库查询。所以我在Python中尝试了类似的思路:a=aifaisnotNoneelse"new"失败了。我认为这是因为如果未定义a,则无法在Python中执行“a=a”。所以我能得出的解决方案是检查locals()和globals(),或者使用try...except表达式:myVar=myVarif'myVar'inlocals()and'myVar'inglobals()else"new"或try:

  9. ruby-on-rails - 功能测试 Authlogic? - 2

    在我的一些Controller中,我有一个before_filter检查用户是否登录?用于CRUD操作。application.rbdeflogged_in?unlesscurrent_userredirect_toroot_pathendendprivatedefcurrent_user_sessionreturn@current_user_sessionifdefined?(@current_user_session)@current_user_session=UserSession.findenddefcurrent_userreturn@current_userifdefine

  10. regex - Ruby 是否有类似于 Perl 6 语法的插件? - 2

    多年来,Perl一直是我首选的编程语言工具之一。Perl6语法看起来像是一个很棒的语言特性。我想知道是否有人开始为Ruby做这样的事情。 最佳答案 如果您想在Ruby中使用实际的Perl6语法,最好的选择是Cardinal,Parrot上的ruby​​编译器。它目前尚未完成并且非常缓慢,但我非常希望它最终成为一个可行的ruby​​实现。它目前大部分处于非事件状态,等待Parrot中的一些基础架构更改以支持改进的解析速度和其他功能。 关于regex-Ruby是否有类似于Perl6语法的插件

随机推荐