Browse Source

修改bug,清楚不必要的库

Bitliker 8 years ago
parent
commit
9b065c2073

+ 3 - 4
WeiChat/build.gradle

@@ -85,7 +85,7 @@ dependencies {
     compile files('libs/asmack.jar')
     compile files('libs/BaiduLBS_Android.jar')
     compile files('libs/cyberplayer-sdk.jar')
-//    compile files('libs/fastjson-1.1.41.jar')
+    //    compile files('libs/fastjson-1.1.41.jar')
     compile files('libs/httpmime-4.2.jar')
     compile files('libs/nineoldandroids.jar')
     compile files('libs/org.xbill.dns_2.1.6.jar')
@@ -112,16 +112,15 @@ dependencies {
     compile('com.facebook.stetho:stetho:1.4.1') {
         force = true
     }
+    //JSON解析
 
-    //JSON解析  
     //https://mvnrepository.com/artifact/com.alibaba/fastjson
-    compile group: 'com.alibaba', name: 'fastjson', version: '1.2.24'
+    compile 'com.alibaba:fastjson:1.2.24'
     compile project(':library-refreshlayout')
     compile files('src/main/jniLibs/pushservice-5.3.0.99.jar')
     compile files('libs/lite-orm-1.7.0.jar')
     //    compile fileTree(include: ['*.jar'], dir: 'libs')
     compile files('libs/Msc.jar')
-    compile project(':library')
     compile files('libs/zhy_treeview.jar')
     compile 'com.readystatesoftware.systembartint:systembartint:1.0.3'
     compile 'com.android.support:support-v4:22.2.1'

+ 0 - 166
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/activity/oa/DepartmentActivity.java

@@ -1,166 +0,0 @@
-package com.xzjmyk.pm.activity.ui.erp.activity.oa;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.FrameLayout;
-import android.widget.TextView;
-
-import com.lidroid.xutils.ViewUtils;
-import com.lidroid.xutils.view.annotation.ViewInject;
-import com.unnamed.b.atv.model.TreeNode;
-import com.unnamed.b.atv.view.AndroidTreeView;
-import com.xzjmyk.pm.activity.R;
-import com.xzjmyk.pm.activity.ui.base.BaseActivity;
-import com.xzjmyk.pm.activity.ui.erp.adapter.oa.SelectableHeaderHolder;
-import com.xzjmyk.pm.activity.ui.erp.db.DBManager;
-import com.xzjmyk.pm.activity.ui.erp.entity.HrorgsEntity;
-import com.xzjmyk.pm.activity.ui.erp.util.CommonUtil;
-import com.xzjmyk.pm.activity.ui.erp.util.ListUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-
-
-public class DepartmentActivity extends BaseActivity {
-
-    @ViewInject(R.id.context_fl)
-    private FrameLayout context_fl;
-    @ViewInject(R.id.mumber_tv)
-    private TextView mumber_tv;
-    @ViewInject(R.id.all_sure_cb)
-    private CheckBox all_sure_cb;
-    private AndroidTreeView tView;
-
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.activity_department);
-        ViewUtils.inject(this);
-        initData();
-    }
-
-    private void initData() {
-        DBManager manager = new DBManager(ct);
-        String master = CommonUtil.getSharedPreferences(ct, "erp_master");
-        List<HrorgsEntity> hrorgsEntities = manager.queryHrorgList(new String[]{master}, "whichsys=?");
-        manager.closeDB();
-        if (ListUtils.isEmpty(hrorgsEntities)) return;
-        List<TreeNode> parent = new ArrayList();//每个节点一个
-        for (int i = 0; i < hrorgsEntities.size(); i++) {//先获取所有父节点
-            if (hrorgsEntities.get(i).getOr_subof() == 0) {
-                parent.add(getNewNode(hrorgsEntities.get(i)));
-                hrorgsEntities.remove(i);
-                i--;
-            }
-        }
-        if (ListUtils.isEmpty(parent)) return;
-        if (!ListUtils.isEmpty(hrorgsEntities))
-            recursive(hrorgsEntities, parent);
-        initView(parent);
-    }
-
-    private void initView(List<TreeNode> parent) {
-        //放界面
-        TreeNode root = TreeNode.root();
-        for (TreeNode e : parent)
-            root.addChild(e);
-        tView = new AndroidTreeView(ct, root);
-        tView.setDefaultAnimation(true);
-        tView.setSelectionModeEnabled(true);
-        tView.setDefaultContainerStyle(R.style.TreeNodeStyleCustom);
-        context_fl.addView(tView.getView());
-        all_sure_cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
-            @Override
-            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
-                Log.i("gongpengming", "onCheckedChanged=" + b);
-                if (b) {
-                    tView.selectAll(true);
-                } else tView.deselectAll();
-            }
-        });
-        findViewById(R.id.sure_tv).setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View view) {
-                Intent intent = new Intent();
-                intent.putParcelableArrayListExtra("data", listSelect);
-                setResult(0x20, intent);
-                finish();
-            }
-        });
-    }
-
-    /**
-     * 递归找当前节点的下级
-     *
-     * @param hrorgsEntities 所有的
-     * @param parent         当前节点
-     * @
-     */
-    private void recursive(List<HrorgsEntity> hrorgsEntities, List<TreeNode> parent) {
-        if (ListUtils.isEmpty(hrorgsEntities) || ListUtils.isEmpty(parent)) return;
-        for (int i = 0; i < hrorgsEntities.size(); i++) {
-            HrorgsEntity e = hrorgsEntities.get(i);
-            for (TreeNode m : parent) {
-                HrorgsEntity che = (HrorgsEntity) m.getValue();
-                if (che.getOr_id() == e.getOr_subof()) {//当前节点捕获到了
-                    m.addChild(getNewNode(e));
-                    hrorgsEntities.remove(i);
-                    i--;
-                }
-            }
-        }
-        recursive(hrorgsEntities, getAllChild(parent));
-    }
-
-    /**
-     * 获取当前父节点所有的子节点
-     *
-     * @param parent
-     * @return
-     */
-    private List<TreeNode> getAllChild(List<TreeNode> parent) {
-        if (ListUtils.isEmpty(parent)) return null;
-        List<TreeNode> allChild = new ArrayList<>();
-        for (TreeNode e : parent) {
-            if (!ListUtils.isEmpty(e.getChildren()))
-                allChild.addAll(e.getChildren());
-        }
-        return allChild;
-    }
-
-
-    private TreeNode getNewNode(HrorgsEntity e) {
-        TreeNode treeNode = new TreeNode(e);
-        treeNode.setViewHolder(new SelectableHeaderHolder(this));
-        return treeNode;
-    }
-
-    private ArrayList<HrorgsEntity> listSelect;
-
-    public void onCheckedChanged(boolean isClicked) {
-        if (listSelect == null)
-            listSelect = new ArrayList<>();
-        else listSelect.clear();
-        List<TreeNode> list = tView.getSelected();
-        if (ListUtils.isEmpty(list)) {
-            return;
-        }
-        for (TreeNode e : list) {
-            if (e.isLeaf() && e.getValue() instanceof HrorgsEntity) {//在最底层
-                listSelect.add((HrorgsEntity) e.getValue());
-            }
-        }
-        setMumberSelect();
-    }
-
-    private void setMumberSelect() {
-        int selectNum = ListUtils.isEmpty(listSelect) ? 0 : listSelect.size();
-        mumber_tv.setText("已选择 " + selectNum + " 个部门");
-    }
-
-}

+ 1 - 1
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/activity/oa/SelectDepartmentActivity.java

@@ -76,7 +76,7 @@ public class SelectDepartmentActivity extends OABaseActivity {
 
 
     private void initData() {
-        DBManager manager = new DBManager(ct);
+        DBManager manager = new DBManager();
         String master = CommonUtil.getSharedPreferences(ct, "erp_master");
         List<HrorgsEntity> hrorgsEntities = manager.queryHrorgList(new String[]{master}, "whichsys=?");
         manager.closeDB();

+ 0 - 84
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/adapter/oa/SelectableHeaderHolder.java

@@ -1,84 +0,0 @@
-package com.xzjmyk.pm.activity.ui.erp.adapter.oa;
-
-import android.content.Context;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.unnamed.b.atv.model.TreeNode;
-import com.xzjmyk.pm.activity.MyApplication;
-import com.xzjmyk.pm.activity.R;
-import com.xzjmyk.pm.activity.ui.erp.activity.oa.DepartmentActivity;
-import com.xzjmyk.pm.activity.ui.erp.entity.HrorgsEntity;
-
-/**
- * Created by Bogdan Melnychuk on 2/15/15.
- */
-public class SelectableHeaderHolder extends TreeNode.BaseNodeViewHolder<HrorgsEntity> {
-    private DepartmentActivity context;
-    private ImageView tagImage;
-
-    public SelectableHeaderHolder(Context context) {
-        super(context);
-        if (context instanceof DepartmentActivity) {
-            this.context = (DepartmentActivity) context;
-        }
-    }
-
-    @Override
-    public View createNodeView(final TreeNode node, HrorgsEntity value) {
-        View view = LayoutInflater.from(MyApplication.getInstance()).
-                inflate(R.layout.item_department, null, false);
-        CheckBox node_cb = (CheckBox) view.findViewById(R.id.node_cb);
-        tagImage = (ImageView) view.findViewById(R.id.image);
-        TextView node_value = (TextView) view.findViewById(R.id.node_value);
-        node_value.setText(value.getOr_name());
-
-        node_cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
-            @Override
-            public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
-                node.setSelected(isChecked);
-                if (isChecked)
-                    for (TreeNode n : node.getChildren()) {
-                        getTreeView().selectNode(n, isChecked);
-                    }
-                if (context != null)
-                    context.onCheckedChanged(isChecked);
-            }
-        });
-        node_cb.setChecked(node.isSelected());
-        setLeafTag(!node.isLeaf());
-        return view;
-    }
-
-    @Override
-    public void toggle(boolean active) {
-        if (!this.mNode.isLeaf())
-            setLeafTag(!active);
-    }
-
-
-    private void setLeafTag(boolean active) {
-        int reid;
-        if (active) {//最底层
-            reid = R.drawable.xiaji;
-        } else {//非最底层
-            reid = R.drawable.xiaji_pass;
-        }
-        tagImage.setImageResource(reid);
-    }
-
-    private boolean isSelected(TreeNode node) {
-        if (node.isSelected()) return true;
-        if (node.getParent() != null) {
-            if (node.getParent().isSelected()) return true;
-            else return isSelected(node.getParent());
-        } else {
-            return false;
-        }
-    }
-
-}

+ 1 - 1
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/db/DBManager.java

@@ -60,7 +60,7 @@ public class DBManager {
     }
 
     public List<B2BMsg> queryB2bList(String[] selectionArgs, String selection) {
-        List<B2BMsg> entity = new ArrayList<B2BMsg>();
+        List<B2BMsg> entity = new ArrayList<>();
         String table = "B2BMSG";
         String groupBy = null;
         String having = null;

+ 0 - 17
WeiChat/src/main/res/layout/activity_department.xml

@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
-    android:id="@+id/activity_department"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical"
-    tools:context="com.xzjmyk.pm.activity.ui.erp.activity.oa.DepartmentActivity">
-
-    <FrameLayout
-        android:id="@+id/context_fl"
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1"/>
-
-    <include layout="@layout/include_select"/>
-</LinearLayout>

+ 3 - 6
WeiChat/src/main/res/layout/activity_select_department.xml

@@ -1,11 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools"
     android:id="@+id/activity_department"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:orientation="vertical"
-    tools:context="com.xzjmyk.pm.activity.ui.erp.activity.oa.DepartmentActivity">
+    android:orientation="vertical">
 
     <RelativeLayout
         android:id="@+id/seach_top"
@@ -43,16 +41,15 @@
         <ListView
             android:id="@+id/search_lv"
             android:layout_width="match_parent"
+            android:layout_height="match_parent"
             android:divider="@color/item_line"
             android:dividerHeight="2px"
-            android:layout_height="match_parent"
             android:visibility="gone" />
 
         <ListView
             android:id="@+id/context_lv"
             android:layout_width="match_parent"
-            android:layout_height="match_parent"
-           />
+            android:layout_height="match_parent" />
     </FrameLayout>
 
     <include layout="@layout/include_select" />

+ 0 - 26
library/.gitignore

@@ -1,26 +0,0 @@
-# Built application files
-*.apk
-*.ap_
-
-# Files for the dex VM
-*.dex
-
-# Java class files
-*.class
-
-# Generated files
-bin/
-gen/
-
-# Local configuration file (sdk path, etc)
-local.properties
-
-# IntelliJ IDEA
-.idea/
-*.iml
-*.iws
-*.ipr
-
-# Gradle
-.gradle
-build/

+ 0 - 24
library/build.gradle

@@ -1,24 +0,0 @@
-apply plugin: 'com.android.library'
-
-android {
-    compileSdkVersion 22
-    buildToolsVersion "22.0.1"
-
-    defaultConfig {
-        minSdkVersion 9
-        targetSdkVersion 22
-//        versionName project.VERSION_NAME
-//        versionCode Integer.parseInt(project.VERSION_CODE)
-    }
-    buildTypes {
-        release {
-            minifyEnabled false
-        }
-    }
-}
-
-dependencies {
-    compile fileTree(dir: 'libs', include: ['*.jar'])
-    compile 'com.android.support:appcompat-v7:22.2.0'
-}
-

+ 0 - 22
library/gradle.properties

@@ -1,22 +0,0 @@
-# Project-wide Gradle settings.
-
-# IDE (e.g. Android Studio) users:
-# Gradle settings configured through the IDE *will override*
-# any settings specified in this file.
-
-# For more details on how to configure your build environment visit
-# http://www.gradle.org/docs/current/userguide/build_environment.html
-
-# Specifies the JVM arguments used for the daemon process.
-# The setting is particularly useful for tweaking memory settings.
-# Default value: -Xmx10248m -XX:MaxPermSize=256m
-# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
-
-# When configured, Gradle will run in incubating parallel mode.
-# This option should only be used with decoupled projects. More details, visit
-# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
-# org.gradle.parallel=true
-
-POM_NAME=AndroidTreeView
-POM_ARTIFACT_ID=atv
-POM_PACKAGING=aar

+ 0 - 17
library/proguard-rules.pro

@@ -1,17 +0,0 @@
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in /Users/bogdan/Library/Android/sdk/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the proguardFiles
-# directive in build.gradle.
-#
-# For more details, see
-#   http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-#   public *;
-#}

+ 0 - 5
library/src/main/AndroidManifest.xml

@@ -1,5 +0,0 @@
-<manifest package="com.unnamed.b.atv">
-
-    <application />
-
-</manifest>

+ 0 - 29
library/src/main/java/com/unnamed/b/atv/holder/SimpleViewHolder.java

@@ -1,29 +0,0 @@
-package com.unnamed.b.atv.holder;
-
-import android.content.Context;
-import android.view.View;
-import android.widget.TextView;
-
-import com.unnamed.b.atv.model.TreeNode;
-
-/**
- * Created by Bogdan Melnychuk on 2/11/15.
- */
-public class SimpleViewHolder extends TreeNode.BaseNodeViewHolder<Object> {
-
-    public SimpleViewHolder(Context context) {
-        super(context);
-    }
-
-    @Override
-    public View createNodeView(TreeNode node, Object value) {
-        final TextView tv = new TextView(context);
-        tv.setText(String.valueOf(value));
-        return tv;
-    }
-
-    @Override
-    public void toggle(boolean active) {
-
-    }
-}

+ 0 - 284
library/src/main/java/com/unnamed/b/atv/model/TreeNode.java

@@ -1,284 +0,0 @@
-package com.unnamed.b.atv.model;
-
-import android.content.Context;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.unnamed.b.atv.R;
-import com.unnamed.b.atv.view.AndroidTreeView;
-import com.unnamed.b.atv.view.TreeNodeWrapperView;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Created by Bogdan Melnychuk on 2/10/15.
- */
-public class TreeNode {
-    public static final String NODES_ID_SEPARATOR = ":";
-
-    private int mId;
-    private int mLastId;
-    private TreeNode mParent;
-    private boolean mSelected;
-    private boolean mSelectable = true;
-    private final List<TreeNode> children;
-    private BaseNodeViewHolder mViewHolder;
-    private TreeNodeClickListener mClickListener;
-    private TreeNodeLongClickListener mLongClickListener;
-    private Object mValue;
-    private boolean mExpanded;
-
-    public static TreeNode root() {
-        TreeNode root = new TreeNode(null);
-        root.setSelectable(false);
-        return root;
-    }
-
-    private int generateId() {
-        return ++mLastId;
-    }
-
-    public TreeNode(Object value) {
-        children = new ArrayList<>();
-        mValue = value;
-    }
-
-    public TreeNode addChild(TreeNode childNode) {
-        childNode.mParent = this;
-        childNode.mId = generateId();
-        children.add(childNode);
-        return this;
-    }
-
-    public TreeNode addChildren(TreeNode... nodes) {
-        for (TreeNode n : nodes) {
-            addChild(n);
-        }
-        return this;
-    }
-
-    public TreeNode addChildren(Collection<TreeNode> nodes) {
-        for (TreeNode n : nodes) {
-            addChild(n);
-        }
-        return this;
-    }
-
-    public int deleteChild(TreeNode child) {
-        for (int i = 0; i < children.size(); i++) {
-            if (child.mId == children.get(i).mId) {
-                children.remove(i);
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    public List<TreeNode> getChildren() {
-        return Collections.unmodifiableList(children);
-    }
-
-    public int size() {
-        return children.size();
-    }
-
-    public TreeNode getParent() {
-        return mParent;
-    }
-
-    public int getId() {
-        return mId;
-    }
-
-    public boolean isLeaf() {
-        return size() == 0;
-    }
-
-    public Object getValue() {
-        return mValue;
-    }
-
-    public boolean isExpanded() {
-        return mExpanded;
-    }
-
-    public TreeNode setExpanded(boolean expanded) {
-        mExpanded = expanded;
-        return this;
-    }
-
-    public void setSelected(boolean selected) {
-        mSelected = selected;
-    }
-
-    public boolean isSelected() {
-        return mSelectable && mSelected;
-    }
-
-    public void setSelectable(boolean selectable) {
-        mSelectable = selectable;
-    }
-
-    public boolean isSelectable() {
-        return mSelectable;
-    }
-
-    public String getPath() {
-        final StringBuilder path = new StringBuilder();
-        TreeNode node = this;
-        while (node.mParent != null) {
-            path.append(node.getId());
-            node = node.mParent;
-            if (node.mParent != null) {
-                path.append(NODES_ID_SEPARATOR);
-            }
-        }
-        return path.toString();
-    }
-
-
-    public int getLevel() {
-        int level = 0;
-        TreeNode root = this;
-        while (root.mParent != null) {
-            root = root.mParent;
-            level++;
-        }
-        return level;
-    }
-
-    public boolean isLastChild() {
-        if (!isRoot()) {
-            int parentSize = mParent.children.size();
-            if (parentSize > 0) {
-                final List<TreeNode> parentChildren = mParent.children;
-                return parentChildren.get(parentSize - 1).mId == mId;
-            }
-        }
-        return false;
-    }
-
-    public TreeNode setViewHolder(BaseNodeViewHolder viewHolder) {
-        mViewHolder = viewHolder;
-        if (viewHolder != null) {
-            viewHolder.mNode = this;
-        }
-        return this;
-    }
-
-    public TreeNode setClickListener(TreeNodeClickListener listener) {
-        mClickListener = listener;
-        return this;
-    }
-
-    public TreeNodeClickListener getClickListener() {
-        return this.mClickListener;
-    }
-
-    public TreeNode setLongClickListener(TreeNodeLongClickListener listener) {
-        mLongClickListener = listener;
-        return this;
-    }
-
-    public TreeNodeLongClickListener getLongClickListener() {
-        return mLongClickListener;
-    }
-
-    public BaseNodeViewHolder getViewHolder() {
-        return mViewHolder;
-    }
-
-    public boolean isFirstChild() {
-        if (!isRoot()) {
-            List<TreeNode> parentChildren = mParent.children;
-            return parentChildren.get(0).mId == mId;
-        }
-        return false;
-    }
-
-    public boolean isRoot() {
-        return mParent == null;
-    }
-
-    public TreeNode getRoot() {
-        TreeNode root = this;
-        while (root.mParent != null) {
-            root = root.mParent;
-        }
-        return root;
-    }
-
-    public interface TreeNodeClickListener {
-        void onClick(TreeNode node, Object value);
-    }
-
-    public interface TreeNodeLongClickListener {
-        boolean onLongClick(TreeNode node, Object value);
-    }
-
-    public static abstract class BaseNodeViewHolder<E> {
-        protected AndroidTreeView tView;
-        protected TreeNode mNode;
-        private View mView;
-        protected int containerStyle;
-        protected Context context;
-
-        public BaseNodeViewHolder(Context context) {
-            this.context = context;
-        }
-
-        public View getView() {
-            if (mView != null) {
-                return mView;
-            }
-            final View nodeView = getNodeView();
-            final TreeNodeWrapperView nodeWrapperView = new TreeNodeWrapperView(nodeView.getContext(), getContainerStyle());
-            nodeWrapperView.insertNodeView(nodeView);
-            mView = nodeWrapperView;
-
-            return mView;
-        }
-
-        public void setTreeViev(AndroidTreeView treeViev) {
-            this.tView = treeViev;
-        }
-
-        public AndroidTreeView getTreeView() {
-            return tView;
-        }
-
-        public void setContainerStyle(int style) {
-            containerStyle = style;
-        }
-
-        public View getNodeView() {
-            return createNodeView(mNode, (E) mNode.getValue());
-        }
-
-        public ViewGroup getNodeItemsView() {
-            return (ViewGroup) getView().findViewById(R.id.node_items);
-        }
-
-        public boolean isInitialized() {
-            return mView != null;
-        }
-
-        public int getContainerStyle() {
-            return containerStyle;
-        }
-
-
-        public abstract View createNodeView(TreeNode node, E value);
-
-        public void toggle(boolean active) {
-            // empty
-        }
-
-        public void toggleSelectionMode(boolean editModeEnabled) {
-            // empty
-        }
-    }
-}

+ 0 - 488
library/src/main/java/com/unnamed/b/atv/view/AndroidTreeView.java

@@ -1,488 +0,0 @@
-package com.unnamed.b.atv.view;
-
-import android.content.Context;
-import android.text.TextUtils;
-import android.view.ContextThemeWrapper;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.Animation;
-import android.view.animation.Transformation;
-import android.widget.LinearLayout;
-import android.widget.ScrollView;
-
-import com.unnamed.b.atv.R;
-import com.unnamed.b.atv.holder.SimpleViewHolder;
-import com.unnamed.b.atv.model.TreeNode;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Created by Bogdan Melnychuk on 2/10/15.
- */
-public class AndroidTreeView {
-    private static final String NODES_PATH_SEPARATOR = ";";
-
-    protected TreeNode mRoot;
-    private Context mContext;
-    private boolean applyForRoot;
-    private int containerStyle = 0;
-    private Class<? extends TreeNode.BaseNodeViewHolder> defaultViewHolderClass = SimpleViewHolder.class;
-    private TreeNode.TreeNodeClickListener nodeClickListener;
-    private TreeNode.TreeNodeLongClickListener nodeLongClickListener;
-    private boolean mSelectionModeEnabled;
-    private boolean mUseDefaultAnimation = false;
-    private boolean use2dScroll = false;
-    private boolean enableAutoToggle = true;
-
-    public AndroidTreeView(Context context) {
-        mContext = context;
-    }
-
-    public void setRoot(TreeNode mRoot) {
-        this.mRoot = mRoot;
-    }
-
-    public AndroidTreeView(Context context, TreeNode root) {
-        mRoot = root;
-        mContext = context;
-    }
-
-    public void setDefaultAnimation(boolean defaultAnimation) {
-        this.mUseDefaultAnimation = defaultAnimation;
-    }
-
-    public void setDefaultContainerStyle(int style) {
-        setDefaultContainerStyle(style, false);
-    }
-
-    public void setDefaultContainerStyle(int style, boolean applyForRoot) {
-        containerStyle = style;
-        this.applyForRoot = applyForRoot;
-    }
-
-    public void setUse2dScroll(boolean use2dScroll) {
-        this.use2dScroll = use2dScroll;
-    }
-
-    public boolean is2dScrollEnabled() {
-        return use2dScroll;
-    }
-
-    public void setUseAutoToggle(boolean enableAutoToggle) {
-        this.enableAutoToggle = enableAutoToggle;
-    }
-
-    public boolean isAutoToggleEnabled() {
-        return enableAutoToggle;
-    }
-
-    public void setDefaultViewHolder(Class<? extends TreeNode.BaseNodeViewHolder> viewHolder) {
-        defaultViewHolderClass = viewHolder;
-    }
-
-    public void setDefaultNodeClickListener(TreeNode.TreeNodeClickListener listener) {
-        nodeClickListener = listener;
-    }
-
-    public void setDefaultNodeLongClickListener(TreeNode.TreeNodeLongClickListener listener) {
-        nodeLongClickListener = listener;
-    }
-
-    public void expandAll() {
-        expandNode(mRoot, true);
-    }
-
-    public void collapseAll() {
-        for (TreeNode n : mRoot.getChildren()) {
-            collapseNode(n, true);
-        }
-    }
-
-
-    public View getView(int style) {
-        final ViewGroup view;
-        if (style > 0) {
-            ContextThemeWrapper newContext = new ContextThemeWrapper(mContext, style);
-            view = use2dScroll ? new TwoDScrollView(newContext) : new ScrollView(newContext);
-        } else {
-            view = use2dScroll ? new TwoDScrollView(mContext) : new ScrollView(mContext);
-        }
-
-        Context containerContext = mContext;
-        if (containerStyle != 0 && applyForRoot) {
-            containerContext = new ContextThemeWrapper(mContext, containerStyle);
-        }
-        final LinearLayout viewTreeItems = new LinearLayout(containerContext, null, containerStyle);
-
-        viewTreeItems.setId(R.id.tree_items);
-        viewTreeItems.setOrientation(LinearLayout.VERTICAL);
-        view.addView(viewTreeItems);
-
-        mRoot.setViewHolder(new TreeNode.BaseNodeViewHolder(mContext) {
-            @Override
-            public View createNodeView(TreeNode node, Object value) {
-                return null;
-            }
-
-            @Override
-            public ViewGroup getNodeItemsView() {
-                return viewTreeItems;
-            }
-        });
-
-        expandNode(mRoot, false);
-        return view;
-    }
-
-    public View getView() {
-        return getView(-1);
-    }
-
-
-    public void expandLevel(int level) {
-        for (TreeNode n : mRoot.getChildren()) {
-            expandLevel(n, level);
-        }
-    }
-
-    private void expandLevel(TreeNode node, int level) {
-        if (node.getLevel() <= level) {
-            expandNode(node, false);
-        }
-        for (TreeNode n : node.getChildren()) {
-            expandLevel(n, level);
-        }
-    }
-
-    public void expandNode(TreeNode node) {
-        expandNode(node, false);
-    }
-
-    public void collapseNode(TreeNode node) {
-        collapseNode(node, false);
-    }
-
-    public String getSaveState() {
-        final StringBuilder builder = new StringBuilder();
-        getSaveState(mRoot, builder);
-        if (builder.length() > 0) {
-            builder.setLength(builder.length() - 1);
-        }
-        return builder.toString();
-    }
-
-    public void restoreState(String saveState) {
-        if (!TextUtils.isEmpty(saveState)) {
-            collapseAll();
-            final String[] openNodesArray = saveState.split(NODES_PATH_SEPARATOR);
-            final Set<String> openNodes = new HashSet<>(Arrays.asList(openNodesArray));
-            restoreNodeState(mRoot, openNodes);
-        }
-    }
-
-    private void restoreNodeState(TreeNode node, Set<String> openNodes) {
-        for (TreeNode n : node.getChildren()) {
-            if (openNodes.contains(n.getPath())) {
-                expandNode(n);
-                restoreNodeState(n, openNodes);
-            }
-        }
-    }
-
-    private void getSaveState(TreeNode root, StringBuilder sBuilder) {
-        for (TreeNode node : root.getChildren()) {
-            if (node.isExpanded()) {
-                sBuilder.append(node.getPath());
-                sBuilder.append(NODES_PATH_SEPARATOR);
-                getSaveState(node, sBuilder);
-            }
-        }
-    }
-
-    public void toggleNode(TreeNode node) {
-        if (node.isExpanded()) {
-            collapseNode(node, false);
-        } else {
-            expandNode(node, false);
-        }
-
-    }
-
-    private void collapseNode(TreeNode node, final boolean includeSubnodes) {
-        node.setExpanded(false);
-        TreeNode.BaseNodeViewHolder nodeViewHolder = getViewHolderForNode(node);
-
-        if (mUseDefaultAnimation) {
-            collapse(nodeViewHolder.getNodeItemsView());
-        } else {
-            nodeViewHolder.getNodeItemsView().setVisibility(View.GONE);
-        }
-        nodeViewHolder.toggle(false);
-        if (includeSubnodes) {
-            for (TreeNode n : node.getChildren()) {
-                collapseNode(n, includeSubnodes);
-            }
-        }
-    }
-
-    private void expandNode(final TreeNode node, boolean includeSubnodes) {
-        node.setExpanded(true);
-        final TreeNode.BaseNodeViewHolder parentViewHolder = getViewHolderForNode(node);
-        parentViewHolder.getNodeItemsView().removeAllViews();
-
-
-        parentViewHolder.toggle(true);
-
-        for (final TreeNode n : node.getChildren()) {
-            addNode(parentViewHolder.getNodeItemsView(), n);
-
-            if (n.isExpanded() || includeSubnodes) {
-                expandNode(n, includeSubnodes);
-            }
-
-        }
-        if (mUseDefaultAnimation) {
-            expand(parentViewHolder.getNodeItemsView());
-        } else {
-            parentViewHolder.getNodeItemsView().setVisibility(View.VISIBLE);
-        }
-
-    }
-
-    private void addNode(ViewGroup container, final TreeNode n) {
-        final TreeNode.BaseNodeViewHolder viewHolder = getViewHolderForNode(n);
-        final View nodeView = viewHolder.getView();
-        container.addView(nodeView);
-        if (mSelectionModeEnabled) {
-            viewHolder.toggleSelectionMode(mSelectionModeEnabled);
-        }
-
-        nodeView.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                if (n.getClickListener() != null) {
-                    n.getClickListener().onClick(n, n.getValue());
-                } else if (nodeClickListener != null) {
-                    nodeClickListener.onClick(n, n.getValue());
-                }
-                if (enableAutoToggle) {
-                    toggleNode(n);
-                }
-            }
-        });
-
-        nodeView.setOnLongClickListener(new View.OnLongClickListener() {
-            @Override
-            public boolean onLongClick(View view) {
-                if (n.getLongClickListener() != null) {
-                    return n.getLongClickListener().onLongClick(n, n.getValue());
-                } else if (nodeLongClickListener != null) {
-                    return nodeLongClickListener.onLongClick(n, n.getValue());
-                }
-                if (enableAutoToggle) {
-                    toggleNode(n);
-                }
-                return false;
-            }
-        });
-    }
-
-    //------------------------------------------------------------
-    //  Selection methods
-
-    public void setSelectionModeEnabled(boolean selectionModeEnabled) {
-        if (!selectionModeEnabled) {
-            // TODO fix double iteration over tree
-            deselectAll();
-        }
-        mSelectionModeEnabled = selectionModeEnabled;
-
-        for (TreeNode node : mRoot.getChildren()) {
-            toggleSelectionMode(node, selectionModeEnabled);
-        }
-
-    }
-
-    public <E> List<E> getSelectedValues(Class<E> clazz) {
-        List<E> result = new ArrayList<>();
-        List<TreeNode> selected = getSelected();
-        for (TreeNode n : selected) {
-            Object value = n.getValue();
-            if (value != null && value.getClass().equals(clazz)) {
-                result.add((E) value);
-            }
-        }
-        return result;
-    }
-
-    public boolean isSelectionModeEnabled() {
-        return mSelectionModeEnabled;
-    }
-
-    private void toggleSelectionMode(TreeNode parent, boolean mSelectionModeEnabled) {
-        toogleSelectionForNode(parent, mSelectionModeEnabled);
-        if (parent.isExpanded()) {
-            for (TreeNode node : parent.getChildren()) {
-                toggleSelectionMode(node, mSelectionModeEnabled);
-            }
-        }
-    }
-
-    public List<TreeNode> getSelected() {
-        if (mSelectionModeEnabled) {
-            return getSelected(mRoot);
-        } else {
-            return new ArrayList<>();
-        }
-    }
-
-    // TODO Do we need to go through whole tree? Save references or consider collapsed nodes as not selected
-    private List<TreeNode> getSelected(TreeNode parent) {
-        List<TreeNode> result = new ArrayList<>();
-        for (TreeNode n : parent.getChildren()) {
-            if (n.isSelected()) {
-                result.add(n);
-            }
-            result.addAll(getSelected(n));
-        }
-        return result;
-    }
-
-    public void selectAll(boolean skipCollapsed) {
-        makeAllSelection(true, skipCollapsed);
-    }
-
-    public void deselectAll() {
-        makeAllSelection(false, false);
-    }
-
-    private void makeAllSelection(boolean selected, boolean skipCollapsed) {
-        if (mSelectionModeEnabled) {
-            for (TreeNode node : mRoot.getChildren()) {
-                selectNode(node, selected, skipCollapsed);
-            }
-        }
-    }
-
-    public void selectNode(TreeNode node, boolean selected) {
-        if (mSelectionModeEnabled) {
-            node.setSelected(selected);
-            toogleSelectionForNode(node, true);
-        }
-    }
-
-    private void selectNode(TreeNode parent, boolean selected, boolean skipCollapsed) {
-        parent.setSelected(selected);
-        toogleSelectionForNode(parent, true);
-        boolean toContinue = skipCollapsed ? parent.isExpanded() : true;
-        if (toContinue) {
-            for (TreeNode node : parent.getChildren()) {
-                selectNode(node, selected, skipCollapsed);
-            }
-        }
-    }
-
-    private void toogleSelectionForNode(TreeNode node, boolean makeSelectable) {
-        TreeNode.BaseNodeViewHolder holder = getViewHolderForNode(node);
-        if (holder.isInitialized()) {
-            getViewHolderForNode(node).toggleSelectionMode(makeSelectable);
-        }
-    }
-
-    private TreeNode.BaseNodeViewHolder getViewHolderForNode(TreeNode node) {
-        TreeNode.BaseNodeViewHolder viewHolder = node.getViewHolder();
-        if (viewHolder == null) {
-            try {
-                final Object object = defaultViewHolderClass.getConstructor(Context.class).newInstance(mContext);
-                viewHolder = (TreeNode.BaseNodeViewHolder) object;
-                node.setViewHolder(viewHolder);
-            } catch (Exception e) {
-                throw new RuntimeException("Could not instantiate class " + defaultViewHolderClass);
-            }
-        }
-        if (viewHolder.getContainerStyle() <= 0) {
-            viewHolder.setContainerStyle(containerStyle);
-        }
-        if (viewHolder.getTreeView() == null) {
-            viewHolder.setTreeViev(this);
-        }
-        return viewHolder;
-    }
-
-    private static void expand(final View v) {
-        v.measure(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
-        final int targetHeight = v.getMeasuredHeight();
-
-        v.getLayoutParams().height = 0;
-        v.setVisibility(View.VISIBLE);
-        Animation a = new Animation() {
-            @Override
-            protected void applyTransformation(float interpolatedTime, Transformation t) {
-                v.getLayoutParams().height = interpolatedTime == 1
-                        ? LinearLayout.LayoutParams.WRAP_CONTENT
-                        : (int) (targetHeight * interpolatedTime);
-                v.requestLayout();
-            }
-
-            @Override
-            public boolean willChangeBounds() {
-                return true;
-            }
-        };
-
-        // 1dp/ms
-        a.setDuration((int) (targetHeight / v.getContext().getResources().getDisplayMetrics().density));
-        v.startAnimation(a);
-    }
-
-    private static void collapse(final View v) {
-        final int initialHeight = v.getMeasuredHeight();
-
-        Animation a = new Animation() {
-            @Override
-            protected void applyTransformation(float interpolatedTime, Transformation t) {
-                if (interpolatedTime == 1) {
-                    v.setVisibility(View.GONE);
-                } else {
-                    v.getLayoutParams().height = initialHeight - (int) (initialHeight * interpolatedTime);
-                    v.requestLayout();
-                }
-            }
-
-            @Override
-            public boolean willChangeBounds() {
-                return true;
-            }
-        };
-
-        // 1dp/ms
-        a.setDuration((int) (initialHeight / v.getContext().getResources().getDisplayMetrics().density));
-        v.startAnimation(a);
-    }
-
-    //-----------------------------------------------------------------
-    //Add / Remove
-
-    public void addNode(TreeNode parent, final TreeNode nodeToAdd) {
-        parent.addChild(nodeToAdd);
-        if (parent.isExpanded()) {
-            final TreeNode.BaseNodeViewHolder parentViewHolder = getViewHolderForNode(parent);
-            addNode(parentViewHolder.getNodeItemsView(), nodeToAdd);
-        }
-    }
-
-    public void removeNode(TreeNode node) {
-        if (node.getParent() != null) {
-            TreeNode parent = node.getParent();
-            int index = parent.deleteChild(node);
-            if (parent.isExpanded() && index >= 0) {
-                final TreeNode.BaseNodeViewHolder parentViewHolder = getViewHolderForNode(parent);
-                parentViewHolder.getNodeItemsView().removeViewAt(index);
-            }
-        }
-    }
-}

+ 0 - 52
library/src/main/java/com/unnamed/b/atv/view/TreeNodeWrapperView.java

@@ -1,52 +0,0 @@
-package com.unnamed.b.atv.view;
-
-import android.content.Context;
-import android.view.ContextThemeWrapper;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-import android.widget.RelativeLayout;
-
-import com.unnamed.b.atv.R;
-
-/**
- * Created by Bogdan Melnychuk on 2/10/15.
- */
-public class TreeNodeWrapperView extends LinearLayout {
-    private LinearLayout nodeItemsContainer;
-    private ViewGroup nodeContainer;
-    private final int containerStyle;
-
-    public TreeNodeWrapperView(Context context, int containerStyle) {
-        super(context);
-        this.containerStyle = containerStyle;
-        init();
-    }
-
-    private void init() {
-        setOrientation(LinearLayout.VERTICAL);
-
-        nodeContainer = new RelativeLayout(getContext());
-        nodeContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
-        nodeContainer.setId(R.id.node_header);
-
-        ContextThemeWrapper newContext = new ContextThemeWrapper(getContext(), containerStyle);
-        nodeItemsContainer = new LinearLayout(newContext, null, containerStyle);
-        nodeItemsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
-        nodeItemsContainer.setId(R.id.node_items);
-        nodeItemsContainer.setOrientation(LinearLayout.VERTICAL);
-        nodeItemsContainer.setVisibility(View.GONE);
-
-        addView(nodeContainer);
-        addView(nodeItemsContainer);
-    }
-
-
-    public void insertNodeView(View nodeView) {
-        nodeContainer.addView(nodeView);
-    }
-
-    public ViewGroup getNodeContainer() {
-        return nodeContainer;
-    }
-}

+ 0 - 1110
library/src/main/java/com/unnamed/b/atv/view/TwoDScrollView.java

@@ -1,1110 +0,0 @@
-package com.unnamed.b.atv.view;
-
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.view.FocusFinder;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.VelocityTracker;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-import android.view.animation.AnimationUtils;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-import android.widget.Scroller;
-import android.widget.TextView;
-
-import java.util.List;
-
-/**
- * Layout container for a view hierarchy that can be scrolled by the user,
- * allowing it to be larger than the physical display.  A TwoDScrollView
- * is a {@link FrameLayout}, meaning you should place one child in it
- * containing the entire contents to scroll; this child may itself be a layout
- * manager with a complex hierarchy of objects.  A child that is often used
- * is a {@link LinearLayout} in a vertical orientation, presenting a vertical
- * array of top-level items that the user can scroll through.
- * <p/>
- * <p>The {@link TextView} class also
- * takes care of its own scrolling, so does not require a TwoDScrollView, but
- * using the two together is possible to achieve the effect of a text view
- * within a larger container.
- */
-public class TwoDScrollView extends FrameLayout {
-    static final int ANIMATED_SCROLL_GAP = 250;
-    static final float MAX_SCROLL_FACTOR = 0.5f;
-
-    private long mLastScroll;
-
-    private final Rect mTempRect = new Rect();
-    private Scroller mScroller;
-
-    /**
-     * Flag to indicate that we are moving focus ourselves. This is so the
-     * code that watches for focus changes initiated outside this TwoDScrollView
-     * knows that it does not have to do anything.
-     */
-    private boolean mTwoDScrollViewMovedFocus;
-
-    /**
-     * Position of the last motion event.
-     */
-    private float mLastMotionY;
-    private float mLastMotionX;
-
-    /**
-     * True when the layout has changed but the traversal has not come through yet.
-     * Ideally the view hierarchy would keep track of this for us.
-     */
-    private boolean mIsLayoutDirty = true;
-
-    /**
-     * The child to give focus to in the event that a child has requested focus while the
-     * layout is dirty. This prevents the scroll from being wrong if the child has not been
-     * laid out before requesting focus.
-     */
-    private View mChildToScrollTo = null;
-
-    /**
-     * True if the user is currently dragging this TwoDScrollView around. This is
-     * not the same as 'is being flinged', which can be checked by
-     * mScroller.isFinished() (flinging begins when the user lifts his finger).
-     */
-    private boolean mIsBeingDragged = false;
-
-    /**
-     * Determines speed during touch scrolling
-     */
-    private VelocityTracker mVelocityTracker;
-
-    /**
-     * Whether arrow scrolling is animated.
-     */
-    private int mTouchSlop;
-    private int mMinimumVelocity;
-    private int mMaximumVelocity;
-
-    public TwoDScrollView(Context context) {
-        super(context);
-        initTwoDScrollView();
-    }
-
-    public TwoDScrollView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        initTwoDScrollView();
-    }
-
-    public TwoDScrollView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        initTwoDScrollView();
-    }
-
-    @Override
-    protected float getTopFadingEdgeStrength() {
-        if (getChildCount() == 0) {
-            return 0.0f;
-        }
-        final int length = getVerticalFadingEdgeLength();
-        if (getScrollY() < length) {
-            return getScrollY() / (float) length;
-        }
-        return 1.0f;
-    }
-
-    @Override
-    protected float getBottomFadingEdgeStrength() {
-        if (getChildCount() == 0) {
-            return 0.0f;
-        }
-        final int length = getVerticalFadingEdgeLength();
-        final int bottomEdge = getHeight() - getPaddingBottom();
-        final int span = getChildAt(0).getBottom() - getScrollY() - bottomEdge;
-        if (span < length) {
-            return span / (float) length;
-        }
-        return 1.0f;
-    }
-
-    @Override
-    protected float getLeftFadingEdgeStrength() {
-        if (getChildCount() == 0) {
-            return 0.0f;
-        }
-        final int length = getHorizontalFadingEdgeLength();
-        if (getScrollX() < length) {
-            return getScrollX() / (float) length;
-        }
-        return 1.0f;
-    }
-
-    @Override
-    protected float getRightFadingEdgeStrength() {
-        if (getChildCount() == 0) {
-            return 0.0f;
-        }
-        final int length = getHorizontalFadingEdgeLength();
-        final int rightEdge = getWidth() - getPaddingRight();
-        final int span = getChildAt(0).getRight() - getScrollX() - rightEdge;
-        if (span < length) {
-            return span / (float) length;
-        }
-        return 1.0f;
-    }
-
-    /**
-     * @return The maximum amount this scroll view will scroll in response to
-     * an arrow event.
-     */
-    public int getMaxScrollAmountVertical() {
-        return (int) (MAX_SCROLL_FACTOR * getHeight());
-    }
-
-    public int getMaxScrollAmountHorizontal() {
-        return (int) (MAX_SCROLL_FACTOR * getWidth());
-    }
-
-    private void initTwoDScrollView() {
-        mScroller = new Scroller(getContext());
-        setFocusable(true);
-        setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
-        setWillNotDraw(false);
-        final ViewConfiguration configuration = ViewConfiguration.get(getContext());
-        mTouchSlop = configuration.getScaledTouchSlop();
-        mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
-        mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
-    }
-
-    @Override
-    public void addView(View child) {
-        if (getChildCount() > 0) {
-            throw new IllegalStateException("TwoDScrollView can host only one direct child");
-        }
-        super.addView(child);
-    }
-
-    @Override
-    public void addView(View child, int index) {
-        if (getChildCount() > 0) {
-            throw new IllegalStateException("TwoDScrollView can host only one direct child");
-        }
-        super.addView(child, index);
-    }
-
-    @Override
-    public void addView(View child, ViewGroup.LayoutParams params) {
-        if (getChildCount() > 0) {
-            throw new IllegalStateException("TwoDScrollView can host only one direct child");
-        }
-        super.addView(child, params);
-    }
-
-    @Override
-    public void addView(View child, int index, ViewGroup.LayoutParams params) {
-        if (getChildCount() > 0) {
-            throw new IllegalStateException("TwoDScrollView can host only one direct child");
-        }
-        super.addView(child, index, params);
-    }
-
-    /**
-     * @return Returns true this TwoDScrollView can be scrolled
-     */
-    private boolean canScroll() {
-        View child = getChildAt(0);
-        if (child != null) {
-            int childHeight = child.getHeight();
-            int childWidth = child.getWidth();
-            return (getHeight() < childHeight + getPaddingTop() + getPaddingBottom()) ||
-                    (getWidth() < childWidth + getPaddingLeft() + getPaddingRight());
-        }
-        return false;
-    }
-
-    @Override
-    public boolean dispatchKeyEvent(KeyEvent event) {
-        // Let the focused view and/or our descendants get the key first
-        boolean handled = super.dispatchKeyEvent(event);
-        if (handled) {
-            return true;
-        }
-        return executeKeyEvent(event);
-    }
-
-    /**
-     * You can call this function yourself to have the scroll view perform
-     * scrolling from a key event, just as if the event had been dispatched to
-     * it by the view hierarchy.
-     *
-     * @param event The key event to execute.
-     * @return Return true if the event was handled, else false.
-     */
-    public boolean executeKeyEvent(KeyEvent event) {
-        mTempRect.setEmpty();
-        if (!canScroll()) {
-            if (isFocused()) {
-                View currentFocused = findFocus();
-                if (currentFocused == this) currentFocused = null;
-                View nextFocused = FocusFinder.getInstance().findNextFocus(this, currentFocused, View.FOCUS_DOWN);
-                return nextFocused != null && nextFocused != this && nextFocused.requestFocus(View.FOCUS_DOWN);
-            }
-            return false;
-        }
-        boolean handled = false;
-        if (event.getAction() == KeyEvent.ACTION_DOWN) {
-            switch (event.getKeyCode()) {
-                case KeyEvent.KEYCODE_DPAD_UP:
-                    if (!event.isAltPressed()) {
-                        handled = arrowScroll(View.FOCUS_UP, false);
-                    } else {
-                        handled = fullScroll(View.FOCUS_UP, false);
-                    }
-                    break;
-                case KeyEvent.KEYCODE_DPAD_DOWN:
-                    if (!event.isAltPressed()) {
-                        handled = arrowScroll(View.FOCUS_DOWN, false);
-                    } else {
-                        handled = fullScroll(View.FOCUS_DOWN, false);
-                    }
-                    break;
-                case KeyEvent.KEYCODE_DPAD_LEFT:
-                    if (!event.isAltPressed()) {
-                        handled = arrowScroll(View.FOCUS_LEFT, true);
-                    } else {
-                        handled = fullScroll(View.FOCUS_LEFT, true);
-                    }
-                    break;
-                case KeyEvent.KEYCODE_DPAD_RIGHT:
-                    if (!event.isAltPressed()) {
-                        handled = arrowScroll(View.FOCUS_RIGHT, true);
-                    } else {
-                        handled = fullScroll(View.FOCUS_RIGHT, true);
-                    }
-                    break;
-            }
-        }
-        return handled;
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-   /*
-   * This method JUST determines whether we want to intercept the motion.
-   * If we return true, onMotionEvent will be called and we do the actual
-   * scrolling there.
-   *
-   * Shortcut the most recurring case: the user is in the dragging
-   * state and he is moving his finger.  We want to intercept this
-   * motion.
-   */
-        final int action = ev.getAction();
-        if ((action == MotionEvent.ACTION_MOVE) && (mIsBeingDragged)) {
-            return true;
-        }
-        if (!canScroll()) {
-            mIsBeingDragged = false;
-            return false;
-        }
-        final float y = ev.getY();
-        final float x = ev.getX();
-        switch (action) {
-            case MotionEvent.ACTION_MOVE:
-       /*
-       * mIsBeingDragged == false, otherwise the shortcut would have caught it. Check
-       * whether the user has moved far enough from his original down touch.
-       */
-       /*
-       * Locally do absolute value. mLastMotionY is set to the y value
-       * of the down event.
-       */
-                final int yDiff = (int) Math.abs(y - mLastMotionY);
-                final int xDiff = (int) Math.abs(x - mLastMotionX);
-                if (yDiff > mTouchSlop || xDiff > mTouchSlop) {
-                    mIsBeingDragged = true;
-                }
-                break;
-
-            case MotionEvent.ACTION_DOWN:
-       /* Remember location of down touch */
-                mLastMotionY = y;
-                mLastMotionX = x;
-
-       /*
-       * If being flinged and user touches the screen, initiate drag;
-       * otherwise don't.  mScroller.isFinished should be false when
-       * being flinged.
-       */
-                mIsBeingDragged = !mScroller.isFinished();
-                break;
-
-            case MotionEvent.ACTION_CANCEL:
-            case MotionEvent.ACTION_UP:
-       /* Release the drag */
-                mIsBeingDragged = false;
-                break;
-        }
-
-   /*
-   * The only time we want to intercept motion events is if we are in the
-   * drag mode.
-   */
-        return mIsBeingDragged;
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-
-        if (ev.getAction() == MotionEvent.ACTION_DOWN && ev.getEdgeFlags() != 0) {
-            // Don't handle edge touches immediately -- they may actually belong to one of our
-            // descendants.
-            return false;
-        }
-
-        if (!canScroll()) {
-            return false;
-        }
-
-        if (mVelocityTracker == null) {
-            mVelocityTracker = VelocityTracker.obtain();
-        }
-        mVelocityTracker.addMovement(ev);
-
-        final int action = ev.getAction();
-        final float y = ev.getY();
-        final float x = ev.getX();
-
-        switch (action) {
-            case MotionEvent.ACTION_DOWN:
-       /*
-       * If being flinged and user touches, stop the fling. isFinished
-       * will be false if being flinged.
-       */
-                if (!mScroller.isFinished()) {
-                    mScroller.abortAnimation();
-                }
-
-                // Remember where the motion event started
-                mLastMotionY = y;
-                mLastMotionX = x;
-                break;
-            case MotionEvent.ACTION_MOVE:
-                // Scroll to follow the motion event
-                int deltaX = (int) (mLastMotionX - x);
-                int deltaY = (int) (mLastMotionY - y);
-                mLastMotionX = x;
-                mLastMotionY = y;
-
-                if (deltaX < 0) {
-                    if (getScrollX() < 0) {
-                        deltaX = 0;
-                    }
-                } else if (deltaX > 0) {
-                    final int rightEdge = getWidth() - getPaddingRight();
-                    final int availableToScroll = getChildAt(0).getRight() - getScrollX() - rightEdge;
-                    if (availableToScroll > 0) {
-                        deltaX = Math.min(availableToScroll, deltaX);
-                    } else {
-                        deltaX = 0;
-                    }
-                }
-                if (deltaY < 0) {
-                    if (getScrollY() < 0) {
-                        deltaY = 0;
-                    }
-                } else if (deltaY > 0) {
-                    final int bottomEdge = getHeight() - getPaddingBottom();
-                    final int availableToScroll = getChildAt(0).getBottom() - getScrollY() - bottomEdge;
-                    if (availableToScroll > 0) {
-                        deltaY = Math.min(availableToScroll, deltaY);
-                    } else {
-                        deltaY = 0;
-                    }
-                }
-                if (deltaY != 0 || deltaX != 0)
-                    scrollBy(deltaX, deltaY);
-                break;
-            case MotionEvent.ACTION_UP:
-                final VelocityTracker velocityTracker = mVelocityTracker;
-                velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
-                int initialXVelocity = (int) velocityTracker.getXVelocity();
-                int initialYVelocity = (int) velocityTracker.getYVelocity();
-                if ((Math.abs(initialXVelocity) + Math.abs(initialYVelocity) > mMinimumVelocity) && getChildCount() > 0) {
-                    fling(-initialXVelocity, -initialYVelocity);
-                }
-                if (mVelocityTracker != null) {
-                    mVelocityTracker.recycle();
-                    mVelocityTracker = null;
-                }
-        }
-        return true;
-    }
-
-    /**
-     * Finds the next focusable component that fits in this View's bounds
-     * (excluding fading edges) pretending that this View's top is located at
-     * the parameter top.
-     *
-     * @param topFocus           look for a candidate is the one at the top of the bounds
-     *                           if topFocus is true, or at the bottom of the bounds if topFocus is
-     *                           false
-     * @param top                the top offset of the bounds in which a focusable must be
-     *                           found (the fading edge is assumed to start at this position)
-     * @param preferredFocusable the View that has highest priority and will be
-     *                           returned if it is within my bounds (null is valid)
-     * @return the next focusable component in the bounds or null if none can be
-     * found
-     */
-    private View findFocusableViewInMyBounds(final boolean topFocus, final int top, final boolean leftFocus, final int left, View preferredFocusable) {
-   /*
-   * The fading edge's transparent side should be considered for focus
-   * since it's mostly visible, so we divide the actual fading edge length
-   * by 2.
-   */
-        final int verticalFadingEdgeLength = getVerticalFadingEdgeLength() / 2;
-        final int topWithoutFadingEdge = top + verticalFadingEdgeLength;
-        final int bottomWithoutFadingEdge = top + getHeight() - verticalFadingEdgeLength;
-        final int horizontalFadingEdgeLength = getHorizontalFadingEdgeLength() / 2;
-        final int leftWithoutFadingEdge = left + horizontalFadingEdgeLength;
-        final int rightWithoutFadingEdge = left + getWidth() - horizontalFadingEdgeLength;
-
-        if ((preferredFocusable != null)
-                && (preferredFocusable.getTop() < bottomWithoutFadingEdge)
-                && (preferredFocusable.getBottom() > topWithoutFadingEdge)
-                && (preferredFocusable.getLeft() < rightWithoutFadingEdge)
-                && (preferredFocusable.getRight() > leftWithoutFadingEdge)) {
-            return preferredFocusable;
-        }
-        return findFocusableViewInBounds(topFocus, topWithoutFadingEdge, bottomWithoutFadingEdge, leftFocus, leftWithoutFadingEdge, rightWithoutFadingEdge);
-    }
-
-    /**
-     * Finds the next focusable component that fits in the specified bounds.
-     * </p>
-     *
-     * @param topFocus look for a candidate is the one at the top of the bounds
-     *                 if topFocus is true, or at the bottom of the bounds if topFocus is
-     *                 false
-     * @param top      the top offset of the bounds in which a focusable must be
-     *                 found
-     * @param bottom   the bottom offset of the bounds in which a focusable must
-     *                 be found
-     * @return the next focusable component in the bounds or null if none can
-     * be found
-     */
-    private View findFocusableViewInBounds(boolean topFocus, int top, int bottom, boolean leftFocus, int left, int right) {
-        List<View> focusables = getFocusables(View.FOCUS_FORWARD);
-        View focusCandidate = null;
-
-   /*
-   * A fully contained focusable is one where its top is below the bound's
-   * top, and its bottom is above the bound's bottom. A partially
-   * contained focusable is one where some part of it is within the
-   * bounds, but it also has some part that is not within bounds.  A fully contained
-   * focusable is preferred to a partially contained focusable.
-   */
-        boolean foundFullyContainedFocusable = false;
-
-        int count = focusables.size();
-        for (int i = 0; i < count; i++) {
-            View view = focusables.get(i);
-            int viewTop = view.getTop();
-            int viewBottom = view.getBottom();
-            int viewLeft = view.getLeft();
-            int viewRight = view.getRight();
-
-            if (top < viewBottom && viewTop < bottom && left < viewRight && viewLeft < right) {
-       /*
-       * the focusable is in the target area, it is a candidate for
-       * focusing
-       */
-                final boolean viewIsFullyContained = (top < viewTop) && (viewBottom < bottom) && (left < viewLeft) && (viewRight < right);
-                if (focusCandidate == null) {
-         /* No candidate, take this one */
-                    focusCandidate = view;
-                    foundFullyContainedFocusable = viewIsFullyContained;
-                } else {
-                    final boolean viewIsCloserToVerticalBoundary =
-                            (topFocus && viewTop < focusCandidate.getTop()) ||
-                                    (!topFocus && viewBottom > focusCandidate.getBottom());
-                    final boolean viewIsCloserToHorizontalBoundary =
-                            (leftFocus && viewLeft < focusCandidate.getLeft()) ||
-                                    (!leftFocus && viewRight > focusCandidate.getRight());
-                    if (foundFullyContainedFocusable) {
-                        if (viewIsFullyContained && viewIsCloserToVerticalBoundary && viewIsCloserToHorizontalBoundary) {
-             /*
-              * We're dealing with only fully contained views, so
-              * it has to be closer to the boundary to beat our
-              * candidate
-              */
-                            focusCandidate = view;
-                        }
-                    } else {
-                        if (viewIsFullyContained) {
-             /* Any fully contained view beats a partially contained view */
-                            focusCandidate = view;
-                            foundFullyContainedFocusable = true;
-                        } else if (viewIsCloserToVerticalBoundary && viewIsCloserToHorizontalBoundary) {
-             /*
-              * Partially contained view beats another partially
-              * contained view if it's closer
-              */
-                            focusCandidate = view;
-                        }
-                    }
-                }
-            }
-        }
-        return focusCandidate;
-    }
-
-    /**
-     * <p>Handles scrolling in response to a "home/end" shortcut press. This
-     * method will scroll the view to the top or bottom and give the focus
-     * to the topmost/bottommost component in the new visible area. If no
-     * component is a good candidate for focus, this scrollview reclaims the
-     * focus.</p>
-     *
-     * @param direction the scroll direction: {@link android.view.View#FOCUS_UP}
-     *                  to go the top of the view or
-     *                  {@link android.view.View#FOCUS_DOWN} to go the bottom
-     * @return true if the key event is consumed by this method, false otherwise
-     */
-    public boolean fullScroll(int direction, boolean horizontal) {
-        if (!horizontal) {
-            boolean down = direction == View.FOCUS_DOWN;
-            int height = getHeight();
-            mTempRect.top = 0;
-            mTempRect.bottom = height;
-            if (down) {
-                int count = getChildCount();
-                if (count > 0) {
-                    View view = getChildAt(count - 1);
-                    mTempRect.bottom = view.getBottom();
-                    mTempRect.top = mTempRect.bottom - height;
-                }
-            }
-            return scrollAndFocus(direction, mTempRect.top, mTempRect.bottom, 0, 0, 0);
-        } else {
-            boolean right = direction == View.FOCUS_DOWN;
-            int width = getWidth();
-            mTempRect.left = 0;
-            mTempRect.right = width;
-            if (right) {
-                int count = getChildCount();
-                if (count > 0) {
-                    View view = getChildAt(count - 1);
-                    mTempRect.right = view.getBottom();
-                    mTempRect.left = mTempRect.right - width;
-                }
-            }
-            return scrollAndFocus(0, 0, 0, direction, mTempRect.top, mTempRect.bottom);
-        }
-    }
-
-    /**
-     * <p>Scrolls the view to make the area defined by <code>top</code> and
-     * <code>bottom</code> visible. This method attempts to give the focus
-     * to a component visible in this area. If no component can be focused in
-     * the new visible area, the focus is reclaimed by this scrollview.</p>
-     *
-     * @param direction the scroll direction: {@link android.view.View#FOCUS_UP}
-     *                  to go upward
-     *                  {@link android.view.View#FOCUS_DOWN} to downward
-     * @param top       the top offset of the new area to be made visible
-     * @param bottom    the bottom offset of the new area to be made visible
-     * @return true if the key event is consumed by this method, false otherwise
-     */
-    private boolean scrollAndFocus(int directionY, int top, int bottom, int directionX, int left, int right) {
-        boolean handled = true;
-        int height = getHeight();
-        int containerTop = getScrollY();
-        int containerBottom = containerTop + height;
-        boolean up = directionY == View.FOCUS_UP;
-        int width = getWidth();
-        int containerLeft = getScrollX();
-        int containerRight = containerLeft + width;
-        boolean leftwards = directionX == View.FOCUS_UP;
-        View newFocused = findFocusableViewInBounds(up, top, bottom, leftwards, left, right);
-        if (newFocused == null) {
-            newFocused = this;
-        }
-        if ((top >= containerTop && bottom <= containerBottom) || (left >= containerLeft && right <= containerRight)) {
-            handled = false;
-        } else {
-            int deltaY = up ? (top - containerTop) : (bottom - containerBottom);
-            int deltaX = leftwards ? (left - containerLeft) : (right - containerRight);
-            doScroll(deltaX, deltaY);
-        }
-        if (newFocused != findFocus() && newFocused.requestFocus(directionY)) {
-            mTwoDScrollViewMovedFocus = true;
-            mTwoDScrollViewMovedFocus = false;
-        }
-        return handled;
-    }
-
-    /**
-     * Handle scrolling in response to an up or down arrow click.
-     *
-     * @param direction The direction corresponding to the arrow key that was
-     *                  pressed
-     * @return True if we consumed the event, false otherwise
-     */
-    public boolean arrowScroll(int direction, boolean horizontal) {
-        View currentFocused = findFocus();
-        if (currentFocused == this) currentFocused = null;
-        View nextFocused = FocusFinder.getInstance().findNextFocus(this, currentFocused, direction);
-        final int maxJump = horizontal ? getMaxScrollAmountHorizontal() : getMaxScrollAmountVertical();
-
-        if (!horizontal) {
-            if (nextFocused != null) {
-                nextFocused.getDrawingRect(mTempRect);
-                offsetDescendantRectToMyCoords(nextFocused, mTempRect);
-                int scrollDelta = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
-                doScroll(0, scrollDelta);
-                nextFocused.requestFocus(direction);
-            } else {
-                // no new focus
-                int scrollDelta = maxJump;
-                if (direction == View.FOCUS_UP && getScrollY() < scrollDelta) {
-                    scrollDelta = getScrollY();
-                } else if (direction == View.FOCUS_DOWN) {
-                    if (getChildCount() > 0) {
-                        int daBottom = getChildAt(0).getBottom();
-                        int screenBottom = getScrollY() + getHeight();
-                        if (daBottom - screenBottom < maxJump) {
-                            scrollDelta = daBottom - screenBottom;
-                        }
-                    }
-                }
-                if (scrollDelta == 0) {
-                    return false;
-                }
-                doScroll(0, direction == View.FOCUS_DOWN ? scrollDelta : -scrollDelta);
-            }
-        } else {
-            if (nextFocused != null) {
-                nextFocused.getDrawingRect(mTempRect);
-                offsetDescendantRectToMyCoords(nextFocused, mTempRect);
-                int scrollDelta = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
-                doScroll(scrollDelta, 0);
-                nextFocused.requestFocus(direction);
-            } else {
-                // no new focus
-                int scrollDelta = maxJump;
-                if (direction == View.FOCUS_UP && getScrollY() < scrollDelta) {
-                    scrollDelta = getScrollY();
-                } else if (direction == View.FOCUS_DOWN) {
-                    if (getChildCount() > 0) {
-                        int daBottom = getChildAt(0).getBottom();
-                        int screenBottom = getScrollY() + getHeight();
-                        if (daBottom - screenBottom < maxJump) {
-                            scrollDelta = daBottom - screenBottom;
-                        }
-                    }
-                }
-                if (scrollDelta == 0) {
-                    return false;
-                }
-                doScroll(direction == View.FOCUS_DOWN ? scrollDelta : -scrollDelta, 0);
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Smooth scroll by a Y delta
-     *
-     * @param delta the number of pixels to scroll by on the Y axis
-     */
-    private void doScroll(int deltaX, int deltaY) {
-        if (deltaX != 0 || deltaY != 0) {
-            smoothScrollBy(deltaX, deltaY);
-        }
-    }
-
-    /**
-     * Like {@link View#scrollBy}, but scroll smoothly instead of immediately.
-     *
-     * @param dx the number of pixels to scroll by on the X axis
-     * @param dy the number of pixels to scroll by on the Y axis
-     */
-    public final void smoothScrollBy(int dx, int dy) {
-        long duration = AnimationUtils.currentAnimationTimeMillis() - mLastScroll;
-        if (duration > ANIMATED_SCROLL_GAP) {
-            mScroller.startScroll(getScrollX(), getScrollY(), dx, dy);
-            awakenScrollBars(mScroller.getDuration());
-            invalidate();
-        } else {
-            if (!mScroller.isFinished()) {
-                mScroller.abortAnimation();
-            }
-            scrollBy(dx, dy);
-        }
-        mLastScroll = AnimationUtils.currentAnimationTimeMillis();
-    }
-
-    /**
-     * Like {@link #scrollTo}, but scroll smoothly instead of immediately.
-     *
-     * @param x the position where to scroll on the X axis
-     * @param y the position where to scroll on the Y axis
-     */
-    public final void smoothScrollTo(int x, int y) {
-        smoothScrollBy(x - getScrollX(), y - getScrollY());
-    }
-
-    /**
-     * <p>The scroll range of a scroll view is the overall height of all of its
-     * children.</p>
-     */
-    @Override
-    protected int computeVerticalScrollRange() {
-        int count = getChildCount();
-        return count == 0 ? getHeight() : (getChildAt(0)).getBottom();
-    }
-
-    @Override
-    protected int computeHorizontalScrollRange() {
-        int count = getChildCount();
-        return count == 0 ? getWidth() : (getChildAt(0)).getRight();
-    }
-
-    @Override
-    protected void measureChild(View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec) {
-        ViewGroup.LayoutParams lp = child.getLayoutParams();
-        int childWidthMeasureSpec;
-        int childHeightMeasureSpec;
-
-        childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec, getPaddingLeft() + getPaddingRight(), lp.width);
-        childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-
-        child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
-    }
-
-    @Override
-    protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed) {
-        final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
-        final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.leftMargin + lp.rightMargin, MeasureSpec.UNSPECIFIED);
-        final int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(lp.topMargin + lp.bottomMargin, MeasureSpec.UNSPECIFIED);
-
-        child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
-    }
-
-    @Override
-    public void computeScroll() {
-        if (mScroller.computeScrollOffset()) {
-            // This is called at drawing time by ViewGroup.  We don't want to
-            // re-show the scrollbars at this point, which scrollTo will do,
-            // so we replicate most of scrollTo here.
-            //
-            //         It's a little odd to call onScrollChanged from inside the drawing.
-            //
-            //         It is, except when you remember that computeScroll() is used to
-            //         animate scrolling. So unless we want to defer the onScrollChanged()
-            //         until the end of the animated scrolling, we don't really have a
-            //         choice here.
-            //
-            //         I agree.  The alternative, which I think would be worse, is to post
-            //         something and tell the subclasses later.  This is bad because there
-            //         will be a window where mScrollX/Y is different from what the app
-            //         thinks it is.
-            //
-            int oldX = getScrollX();
-            int oldY = getScrollY();
-            int x = mScroller.getCurrX();
-            int y = mScroller.getCurrY();
-            if (getChildCount() > 0) {
-                View child = getChildAt(0);
-                scrollTo(clamp(x, getWidth() - getPaddingRight() - getPaddingLeft(), child.getWidth()),
-                        clamp(y, getHeight() - getPaddingBottom() - getPaddingTop(), child.getHeight()));
-            } else {
-                scrollTo(x, y);
-            }
-            if (oldX != getScrollX() || oldY != getScrollY()) {
-                onScrollChanged(getScrollX(), getScrollY(), oldX, oldY);
-            }
-
-            // Keep on drawing until the animation has finished.
-            postInvalidate();
-        }
-    }
-
-    /**
-     * Scrolls the view to the given child.
-     *
-     * @param child the View to scroll to
-     */
-    private void scrollToChild(View child) {
-        child.getDrawingRect(mTempRect);
-   /* Offset from child's local coordinates to TwoDScrollView coordinates */
-        offsetDescendantRectToMyCoords(child, mTempRect);
-        int scrollDelta = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
-        if (scrollDelta != 0) {
-            scrollBy(0, scrollDelta);
-        }
-    }
-
-    /**
-     * If rect is off screen, scroll just enough to get it (or at least the
-     * first screen size chunk of it) on screen.
-     *
-     * @param rect      The rectangle.
-     * @param immediate True to scroll immediately without animation
-     * @return true if scrolling was performed
-     */
-    private boolean scrollToChildRect(Rect rect, boolean immediate) {
-        final int delta = computeScrollDeltaToGetChildRectOnScreen(rect);
-        final boolean scroll = delta != 0;
-        if (scroll) {
-            if (immediate) {
-                scrollBy(0, delta);
-            } else {
-                smoothScrollBy(0, delta);
-            }
-        }
-        return scroll;
-    }
-
-    /**
-     * Compute the amount to scroll in the Y direction in order to get
-     * a rectangle completely on the screen (or, if taller than the screen,
-     * at least the first screen size chunk of it).
-     *
-     * @param rect The rect.
-     * @return The scroll delta.
-     */
-    protected int computeScrollDeltaToGetChildRectOnScreen(Rect rect) {
-        if (getChildCount() == 0) return 0;
-        int height = getHeight();
-        int screenTop = getScrollY();
-        int screenBottom = screenTop + height;
-        int fadingEdge = getVerticalFadingEdgeLength();
-        // leave room for top fading edge as long as rect isn't at very top
-        if (rect.top > 0) {
-            screenTop += fadingEdge;
-        }
-
-        // leave room for bottom fading edge as long as rect isn't at very bottom
-        if (rect.bottom < getChildAt(0).getHeight()) {
-            screenBottom -= fadingEdge;
-        }
-        int scrollYDelta = 0;
-        if (rect.bottom > screenBottom && rect.top > screenTop) {
-            // need to move down to get it in view: move down just enough so
-            // that the entire rectangle is in view (or at least the first
-            // screen size chunk).
-            if (rect.height() > height) {
-                // just enough to get screen size chunk on
-                scrollYDelta += (rect.top - screenTop);
-            } else {
-                // get entire rect at bottom of screen
-                scrollYDelta += (rect.bottom - screenBottom);
-            }
-
-            // make sure we aren't scrolling beyond the end of our content
-            int bottom = getChildAt(0).getBottom();
-            int distanceToBottom = bottom - screenBottom;
-            scrollYDelta = Math.min(scrollYDelta, distanceToBottom);
-
-        } else if (rect.top < screenTop && rect.bottom < screenBottom) {
-            // need to move up to get it in view: move up just enough so that
-            // entire rectangle is in view (or at least the first screen
-            // size chunk of it).
-
-            if (rect.height() > height) {
-                // screen size chunk
-                scrollYDelta -= (screenBottom - rect.bottom);
-            } else {
-                // entire rect at top
-                scrollYDelta -= (screenTop - rect.top);
-            }
-
-            // make sure we aren't scrolling any further than the top our content
-            scrollYDelta = Math.max(scrollYDelta, -getScrollY());
-        }
-        return scrollYDelta;
-    }
-
-    @Override
-    public void requestChildFocus(View child, View focused) {
-        if (!mTwoDScrollViewMovedFocus) {
-            if (!mIsLayoutDirty) {
-                scrollToChild(focused);
-            } else {
-                // The child may not be laid out yet, we can't compute the scroll yet
-                mChildToScrollTo = focused;
-            }
-        }
-        super.requestChildFocus(child, focused);
-    }
-
-    /**
-     * When looking for focus in children of a scroll view, need to be a little
-     * more careful not to give focus to something that is scrolled off screen.
-     * <p/>
-     * This is more expensive than the default {@link android.view.ViewGroup}
-     * implementation, otherwise this behavior might have been made the default.
-     */
-    @Override
-    protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
-        // convert from forward / backward notation to up / down / left / right
-        // (ugh).
-        if (direction == View.FOCUS_FORWARD) {
-            direction = View.FOCUS_DOWN;
-        } else if (direction == View.FOCUS_BACKWARD) {
-            direction = View.FOCUS_UP;
-        }
-
-        final View nextFocus = previouslyFocusedRect == null ?
-                FocusFinder.getInstance().findNextFocus(this, null, direction) :
-                FocusFinder.getInstance().findNextFocusFromRect(this,
-                        previouslyFocusedRect, direction);
-
-        if (nextFocus == null) {
-            return false;
-        }
-
-        return nextFocus.requestFocus(direction, previouslyFocusedRect);
-    }
-
-    @Override
-    public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) {
-        // offset into coordinate space of this scroll view
-        rectangle.offset(child.getLeft() - child.getScrollX(), child.getTop() - child.getScrollY());
-        return scrollToChildRect(rectangle, immediate);
-    }
-
-    @Override
-    public void requestLayout() {
-        mIsLayoutDirty = true;
-        super.requestLayout();
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        super.onLayout(changed, l, t, r, b);
-        mIsLayoutDirty = false;
-        // Give a child focus if it needs it
-        if (mChildToScrollTo != null && isViewDescendantOf(mChildToScrollTo, this)) {
-            scrollToChild(mChildToScrollTo);
-        }
-        mChildToScrollTo = null;
-
-        // Calling this with the present values causes it to re-clam them
-        scrollTo(getScrollX(), getScrollY());
-    }
-
-    @Override
-    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-        super.onSizeChanged(w, h, oldw, oldh);
-
-        View currentFocused = findFocus();
-        if (null == currentFocused || this == currentFocused)
-            return;
-
-        // If the currently-focused view was visible on the screen when the
-        // screen was at the old height, then scroll the screen to make that
-        // view visible with the new screen height.
-        currentFocused.getDrawingRect(mTempRect);
-        offsetDescendantRectToMyCoords(currentFocused, mTempRect);
-        int scrollDeltaX = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
-        int scrollDeltaY = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
-        doScroll(scrollDeltaX, scrollDeltaY);
-    }
-
-    /**
-     * Return true if child is an descendant of parent, (or equal to the parent).
-     */
-    private boolean isViewDescendantOf(View child, View parent) {
-        if (child == parent) {
-            return true;
-        }
-
-        final ViewParent theParent = child.getParent();
-        return (theParent instanceof ViewGroup) && isViewDescendantOf((View) theParent, parent);
-    }
-
-    /**
-     * Fling the scroll view
-     *
-     * @param velocityY The initial velocity in the Y direction. Positive
-     *                  numbers mean that the finger/curor is moving down the screen,
-     *                  which means we want to scroll towards the top.
-     */
-    public void fling(int velocityX, int velocityY) {
-        if (getChildCount() > 0) {
-            int height = getHeight() - getPaddingBottom() - getPaddingTop();
-            int bottom = getChildAt(0).getHeight();
-            int width = getWidth() - getPaddingRight() - getPaddingLeft();
-            int right = getChildAt(0).getWidth();
-
-            mScroller.fling(getScrollX(), getScrollY(), velocityX, velocityY, 0, right - width, 0, bottom - height);
-
-            final boolean movingDown = velocityY > 0;
-            final boolean movingRight = velocityX > 0;
-
-            View newFocused = findFocusableViewInMyBounds(movingRight, mScroller.getFinalX(), movingDown, mScroller.getFinalY(), findFocus());
-            if (newFocused == null) {
-                newFocused = this;
-            }
-
-            if (newFocused != findFocus() && newFocused.requestFocus(movingDown ? View.FOCUS_DOWN : View.FOCUS_UP)) {
-                mTwoDScrollViewMovedFocus = true;
-                mTwoDScrollViewMovedFocus = false;
-            }
-
-            awakenScrollBars(mScroller.getDuration());
-            invalidate();
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p/>
-     * <p>This version also clamps the scrolling to the bounds of our child.
-     */
-    public void scrollTo(int x, int y) {
-        // we rely on the fact the View.scrollBy calls scrollTo.
-        if (getChildCount() > 0) {
-            View child = getChildAt(0);
-            x = clamp(x, getWidth() - getPaddingRight() - getPaddingLeft(), child.getWidth());
-            y = clamp(y, getHeight() - getPaddingBottom() - getPaddingTop(), child.getHeight());
-            if (x != getScrollX() || y != getScrollY()) {
-                super.scrollTo(x, y);
-            }
-        }
-    }
-
-    private int clamp(int n, int my, int child) {
-        if (my >= child || n < 0) {
-     /* my >= child is this case:
-      *                    |--------------- me ---------------|
-      *     |------ child ------|
-      * or
-      *     |--------------- me ---------------|
-      *            |------ child ------|
-      * or
-      *     |--------------- me ---------------|
-      *                                  |------ child ------|
-      *
-      * n < 0 is this case:
-      *     |------ me ------|
-      *                    |-------- child --------|
-      *     |-- mScrollX --|
-      */
-            return 0;
-        }
-        if ((my + n) > child) {
-     /* this case:
-      *                    |------ me ------|
-      *     |------ child ------|
-      *     |-- mScrollX --|
-      */
-            return child - my;
-        }
-        return n;
-    }
-}

+ 0 - 6
library/src/main/res/values/ids.xml

@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <item name="node_header" type="id" />
-    <item name="node_items" type="id" />
-    <item name="tree_items" type="id" />
-</resources>

+ 0 - 7
library/src/main/res/values/styles.xml

@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-
-    <style name="TreeNodeStyle">
-        <item name="android:paddingLeft">20dp</item>
-    </style>
-</resources>

+ 1 - 1
settings.gradle

@@ -1,2 +1,2 @@
-include ':pullToRefershLibraryMy', ':materialdialogs', ':MPAndroidChart', ':libedittextformlibrary', ':libfloatingactionbutton', ':libbdupdatesdk', ':library-viewpager-indicator', ':library-swipemenu_lv', ':lib-zxing', ':library-refreshlayout', ':library'
+include ':pullToRefershLibraryMy', ':materialdialogs', ':MPAndroidChart', ':libedittextformlibrary', ':libfloatingactionbutton', ':libbdupdatesdk', ':library-viewpager-indicator', ':library-swipemenu_lv', ':lib-zxing', ':library-refreshlayout'
 include ':WeiChat'