Resource 1st version... Visible

This commit is contained in:
Caesar2011
2018-09-16 18:59:55 +02:00
parent 95cef20bb8
commit e21b2e99f2
18 changed files with 869 additions and 6 deletions

2
.idea/misc.xml generated
View File

@@ -25,5 +25,5 @@
</value>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8 (2)" project-jdk-type="JavaSDK" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK" />
</project>

2
.idea/modules.xml generated
View File

@@ -2,7 +2,7 @@
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/FUPlanner.iml" filepath="$PROJECT_DIR$/.idea/FUPlanner.iml" />
<module fileurl="file://$PROJECT_DIR$/FUPlanner.iml" filepath="$PROJECT_DIR$/FUPlanner.iml" />
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
</modules>
</component>

1
.idea/vcs.xml generated
View File

@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@@ -38,6 +38,8 @@ class ModDetailAdapter extends FragmentStatePagerAdapter {
return ModDetailEventFragment.newInstance(mItemPos);
case ModulePart.GRADEBOOK:
return ModDetailGradebookFragment.newInstance(mItemPos);
case ModulePart.RESOURCES:
return ModDetailResourceFragment.newInstance(mItemPos);
default:
return null;
}
@@ -57,6 +59,8 @@ class ModDetailAdapter extends FragmentStatePagerAdapter {
return this.mContext.getResources().getString(R.string.events);
case ModulePart.GRADEBOOK:
return this.mContext.getResources().getString(R.string.gradebook);
case ModulePart.RESOURCES:
return this.mContext.getResources().getString(R.string.resourcen);
default:
return "";
}

View File

@@ -0,0 +1,34 @@
package de.sebse.fuplanner.fragments.moddetails;
import java.util.ArrayList;
import java.util.List;
import de.sebse.fuplanner.services.KVV.types.Modules;
import de.sebse.fuplanner.services.KVV.types.Resource;
import de.sebse.fuplanner.tools.ui.treeview.TreeNode;
import de.sebse.fuplanner.tools.ui.treeview.TreeViewAdapter;
import de.sebse.fuplanner.tools.ui.treeview.TreeViewBinder;
class ModDetailResourceAdapter extends TreeViewAdapter {
private Modules.Module mValue;
public ModDetailResourceAdapter(List<? extends TreeViewBinder> viewBinders) {
super(viewBinders);
mValue = null;
}
public void setModule(Modules.Module module) {
mValue = module;
this.setModule();
}
public void setModule() {
if (mValue == null || mValue.resources == null) {
return;
}
List<TreeNode> nodes = new ArrayList<>();
for (Resource res: mValue.resources) {
nodes.add(res.getTreeNode());
}
refresh(nodes);
}
}

View File

@@ -0,0 +1,132 @@
package de.sebse.fuplanner.fragments.moddetails;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import java.util.Arrays;
import de.sebse.fuplanner.MainActivity;
import de.sebse.fuplanner.R;
import de.sebse.fuplanner.services.KVV.KVV;
import de.sebse.fuplanner.services.KVV.types.Modules;
import de.sebse.fuplanner.tools.logging.Logger;
import de.sebse.fuplanner.tools.ui.treeview.DirectoryNodeBinder;
import de.sebse.fuplanner.tools.ui.treeview.FileNodeBinder;
import de.sebse.fuplanner.tools.ui.treeview.TreeNode;
import de.sebse.fuplanner.tools.ui.treeview.TreeViewAdapter;
/**
* A simple {@link Fragment} subclass.
* Use the {@link ModDetailResourceFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class ModDetailResourceFragment extends Fragment {
private static final String ARG_POSITION = "itemPosition";
private String mItemPos;
private final Logger log = new Logger(this);
private ModDetailResourceAdapter adapter;
private SwipeRefreshLayout swipeLayout;
public ModDetailResourceFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param itemPosition Item position in module list.
* @return A new instance of fragment ModDetailAnnounceFragment.
*/
public static ModDetailResourceFragment newInstance(String itemPosition) {
ModDetailResourceFragment fragment = new ModDetailResourceFragment();
Bundle args = new Bundle();
args.putString(ARG_POSITION, itemPosition);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mItemPos = getArguments().getString(ARG_POSITION);
}
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_recycler_view, container, false);
// Set the adapter
Context context = view.getContext();
RecyclerView recyclerView = view.findViewById(R.id.list);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
adapter = new ModDetailResourceAdapter(Arrays.asList(new FileNodeBinder(), new DirectoryNodeBinder()));
adapter.setOnTreeNodeListener(new TreeViewAdapter.OnTreeNodeListener() {
@Override
public boolean onClick(TreeNode node, RecyclerView.ViewHolder holder) {
if (!node.isLeaf()) {
//Update and toggle the node.
onToggle(!node.isExpand(), holder);
// if (!node.isExpand())
// adapter.collapseBrotherNode(node);
}
return false;
}
@Override
public void onToggle(boolean isExpand, RecyclerView.ViewHolder holder) {
DirectoryNodeBinder.ViewHolder dirViewHolder = (DirectoryNodeBinder.ViewHolder) holder;
final ImageView ivArrow = dirViewHolder.getIvArrow();
int rotateDegree = isExpand ? 90 : -90;
ivArrow.animate().rotationBy(rotateDegree)
.start();
}
});
recyclerView.setAdapter(adapter);
// Getting SwipeContainerLayout
swipeLayout = view.findViewById(R.id.swipe_container);
// Adding Listener
swipeLayout.setOnRefreshListener(() -> refresh(true));
refresh(false);
return view;
}
private void refresh(boolean forceRefresh) {
if (getActivity() != null) {
KVV kvv = ((MainActivity) getActivity()).getKVV();
kvv.getModule(mItemPos, (Modules.Module module) -> {
adapter.setModule(module);
kvv.getModuleResources(module, success1 -> {
adapter.setModule();
swipeLayout.setRefreshing(false);
}, error -> {
swipeLayout.setRefreshing(false);
log.e(error);
}, forceRefresh);
}, error -> {
swipeLayout.setRefreshing(false);
log.e(error);
}, forceRefresh);
}
}
}

View File

@@ -7,7 +7,8 @@ class ModulePart {
static final int ASSIGNMENT = 3;
static final int EVENT = 4;
static final int GRADEBOOK = 5;
private static final int[] pages = new int[]{OVERVIEW, ANNOUNCEMENT, ASSIGNMENT, EVENT, GRADEBOOK};
static final int RESOURCES = 6;
private static final int[] pages = new int[]{OVERVIEW, ANNOUNCEMENT, ASSIGNMENT, EVENT, GRADEBOOK, RESOURCES};
static int getPageCount() {
return pages.length;

View File

@@ -3,6 +3,9 @@ package de.sebse.fuplanner.services.KVV.types;
import java.io.Serializable;
import java.util.ArrayList;
import de.sebse.fuplanner.tools.ui.treeview.Dir;
import de.sebse.fuplanner.tools.ui.treeview.TreeNode;
public abstract class Resource implements Serializable {
@@ -47,9 +50,9 @@ public abstract class Resource implements Serializable {
return visible;
}
public abstract TreeNode getTreeNode();
public static class File extends Resource {
private final String type;
public File(String author, String title, long modifiedDate, String url, boolean visible, String container, String type) {
@@ -67,6 +70,11 @@ public abstract class Resource implements Serializable {
", type='" + type + '\'' +
'}';
}
@Override
public TreeNode getTreeNode() {
return new TreeNode<>(new de.sebse.fuplanner.tools.ui.treeview.File(title));
}
}
public static class Folder extends Resource{
@@ -99,6 +107,15 @@ public abstract class Resource implements Serializable {
", childs='" + childs + '\'' +
'}';
}
@Override
public TreeNode getTreeNode() {
TreeNode<Dir> dir = new TreeNode<>(new Dir(title));
for (Resource res: childs) {
dir.addChild(res.getTreeNode());
}
return dir;
}
}
}

View File

@@ -0,0 +1,21 @@
package de.sebse.fuplanner.tools.ui.treeview;
import de.sebse.fuplanner.R;
/**
* Created by tlh on 2016/10/1 :)
*/
public class Dir implements LayoutItemType {
public String dirName;
public Dir(String dirName) {
this.dirName = dirName;
}
@Override
public int getLayoutId() {
return R.layout.item_dir;
}
}

View File

@@ -0,0 +1,55 @@
package de.sebse.fuplanner.tools.ui.treeview;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import de.sebse.fuplanner.R;
/**
* Created by tlh on 2016/10/1 :)
*/
public class DirectoryNodeBinder extends TreeViewBinder<DirectoryNodeBinder.ViewHolder> {
@Override
public ViewHolder provideViewHolder(View itemView) {
return new ViewHolder(itemView);
}
@Override
public void bindView(ViewHolder holder, int position, TreeNode node) {
holder.ivArrow.setRotation(0);
holder.ivArrow.setImageResource(R.drawable.ic_keyboard_arrow_right_black_18dp);
int rotateDegree = node.isExpand() ? 90 : 0;
holder.ivArrow.setRotation(rotateDegree);
Dir dirNode = (Dir) node.getContent();
holder.tvName.setText(dirNode.dirName);
if (node.isLeaf())
holder.ivArrow.setVisibility(View.INVISIBLE);
else holder.ivArrow.setVisibility(View.VISIBLE);
}
@Override
public int getLayoutId() {
return R.layout.item_dir;
}
public static class ViewHolder extends TreeViewBinder.ViewHolder {
private ImageView ivArrow;
private TextView tvName;
public ViewHolder(View rootView) {
super(rootView);
this.ivArrow = (ImageView) rootView.findViewById(R.id.iv_arrow);
this.tvName = (TextView) rootView.findViewById(R.id.tv_name);
}
public ImageView getIvArrow() {
return ivArrow;
}
public TextView getTvName() {
return tvName;
}
}
}

View File

@@ -0,0 +1,21 @@
package de.sebse.fuplanner.tools.ui.treeview;
import de.sebse.fuplanner.R;
/**
* Created by tlh on 2016/10/1 :)
*/
public class File implements LayoutItemType {
public String fileName;
public File(String fileName) {
this.fileName = fileName;
}
@Override
public int getLayoutId() {
return R.layout.item_file;
}
}

View File

@@ -0,0 +1,38 @@
package de.sebse.fuplanner.tools.ui.treeview;
import android.view.View;
import android.widget.TextView;
import de.sebse.fuplanner.R;
/**
* Created by tlh on 2016/10/1 :)
*/
public class FileNodeBinder extends TreeViewBinder<FileNodeBinder.ViewHolder> {
@Override
public ViewHolder provideViewHolder(View itemView) {
return new ViewHolder(itemView);
}
@Override
public void bindView(ViewHolder holder, int position, TreeNode node) {
File fileNode = (File) node.getContent();
holder.tvName.setText(fileNode.fileName);
}
@Override
public int getLayoutId() {
return R.layout.item_file;
}
public class ViewHolder extends TreeViewBinder.ViewHolder {
public TextView tvName;
public ViewHolder(View rootView) {
super(rootView);
this.tvName = (TextView) rootView.findViewById(R.id.tv_name);
}
}
}

View File

@@ -0,0 +1,9 @@
package de.sebse.fuplanner.tools.ui.treeview;
/**
* Created by tlh on 2016/10/1 :)
*/
public interface LayoutItemType {
int getLayoutId();
}

View File

@@ -0,0 +1,149 @@
package de.sebse.fuplanner.tools.ui.treeview;
import android.support.annotation.NonNull;
import java.util.ArrayList;
import java.util.List;
/**
* Created by tlh on 2016/10/1 :)
*/
public class TreeNode<T extends LayoutItemType> implements Cloneable {
private T content;
private TreeNode parent;
private List<TreeNode> childList;
private boolean isExpand;
private boolean isLocked;
//the tree high
private int height = UNDEFINE;
private static final int UNDEFINE = -1;
public TreeNode(@NonNull T content) {
this.content = content;
this.childList = new ArrayList<>();
}
public int getHeight() {
if (isRoot())
height = 0;
else if (height == UNDEFINE)
height = parent.getHeight() + 1;
return height;
}
public boolean isRoot() {
return parent == null;
}
public boolean isLeaf() {
return childList == null || childList.isEmpty();
}
public void setContent(T content) {
this.content = content;
}
public T getContent() {
return content;
}
public List<TreeNode> getChildList() {
return childList;
}
public void setChildList(List<TreeNode> childList) {
this.childList.clear();
for (TreeNode treeNode : childList) {
addChild(treeNode);
}
}
public TreeNode addChild(TreeNode node) {
if (childList == null)
childList = new ArrayList<>();
childList.add(node);
node.parent = this;
return this;
}
public boolean toggle() {
isExpand = !isExpand;
return isExpand;
}
public void collapse() {
if (isExpand) {
isExpand = false;
}
}
public void collapseAll() {
if (childList == null || childList.isEmpty()) {
return;
}
for (TreeNode child : this.childList) {
child.collapseAll();
}
}
public void expand() {
if (!isExpand) {
isExpand = true;
}
}
public void expandAll() {
expand();
if (childList == null || childList.isEmpty()) {
return;
}
for (TreeNode child : this.childList) {
child.expandAll();
}
}
public boolean isExpand() {
return isExpand;
}
public void setParent(TreeNode parent) {
this.parent = parent;
}
public TreeNode getParent() {
return parent;
}
public TreeNode<T> lock() {
isLocked = true;
return this;
}
public TreeNode<T> unlock() {
isLocked = false;
return this;
}
public boolean isLocked() {
return isLocked;
}
@Override
public String toString() {
return "TreeNode{" +
"content=" + this.content +
", parent=" + (parent == null ? "null" : parent.getContent().toString()) +
", childList=" + (childList == null ? "null" : childList.toString()) +
", isExpand=" + isExpand +
'}';
}
@Override
protected TreeNode<T> clone() throws CloneNotSupportedException {
TreeNode<T> clone = new TreeNode<>(this.content);
clone.isExpand = this.isExpand;
return clone;
}
}

View File

@@ -0,0 +1,320 @@
package de.sebse.fuplanner.tools.ui.treeview;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.util.DiffUtil;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Created by tlh on 2016/10/1 :)
*/
public class TreeViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final String KEY_IS_EXPAND = "IS_EXPAND";
private final List<? extends TreeViewBinder> viewBinders;
private List<TreeNode> displayNodes;
private int padding = 30;
private OnTreeNodeListener onTreeNodeListener;
private boolean toCollapseChild;
public TreeViewAdapter(List<? extends TreeViewBinder> viewBinders) {
this(null, viewBinders);
}
public TreeViewAdapter(List<TreeNode> nodes, List<? extends TreeViewBinder> viewBinders) {
displayNodes = new ArrayList<>();
if (nodes != null)
findDisplayNodes(nodes);
this.viewBinders = viewBinders;
}
/**
* 从nodes的结点中寻找展开了的非叶结点添加到displayNodes中。
*
* @param nodes 基准点
*/
private void findDisplayNodes(List<TreeNode> nodes) {
for (TreeNode node : nodes) {
displayNodes.add(node);
if (!node.isLeaf() && node.isExpand())
findDisplayNodes(node.getChildList());
}
}
@Override
public int getItemViewType(int position) {
return displayNodes.get(position).getContent().getLayoutId();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(viewType, parent, false);
if (viewBinders.size() == 1)
return viewBinders.get(0).provideViewHolder(v);
for (TreeViewBinder viewBinder : viewBinders) {
if (viewBinder.getLayoutId() == viewType)
return viewBinder.provideViewHolder(v);
}
return viewBinders.get(0).provideViewHolder(v);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position, List<Object> payloads) {
if (payloads != null && !payloads.isEmpty()) {
Bundle b = (Bundle) payloads.get(0);
for (String key : b.keySet()) {
switch (key) {
case KEY_IS_EXPAND:
if (onTreeNodeListener != null)
onTreeNodeListener.onToggle(b.getBoolean(key), holder);
break;
}
}
}
super.onBindViewHolder(holder, position, payloads);
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
holder.itemView.setPadding(displayNodes.get(position).getHeight() * padding, 3, 3, 3);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
TreeNode selectedNode = displayNodes.get(holder.getLayoutPosition());
// Prevent multi-click during the short interval.
try {
long lastClickTime = (long) holder.itemView.getTag();
if (System.currentTimeMillis() - lastClickTime < 500)
return;
} catch (Exception e) {
holder.itemView.setTag(System.currentTimeMillis());
}
holder.itemView.setTag(System.currentTimeMillis());
if (onTreeNodeListener != null && onTreeNodeListener.onClick(selectedNode, holder))
return;
if (selectedNode.isLeaf())
return;
// This TreeNode was locked to click.
if (selectedNode.isLocked()) return;
boolean isExpand = selectedNode.isExpand();
int positionStart = displayNodes.indexOf(selectedNode) + 1;
if (!isExpand) {
notifyItemRangeInserted(positionStart, addChildNodes(selectedNode, positionStart));
} else {
notifyItemRangeRemoved(positionStart, removeChildNodes(selectedNode, true));
}
}
});
for (TreeViewBinder viewBinder : viewBinders) {
if (viewBinder.getLayoutId() == displayNodes.get(position).getContent().getLayoutId())
viewBinder.bindView(holder, position, displayNodes.get(position));
}
}
private int addChildNodes(TreeNode pNode, int startIndex) {
List<TreeNode> childList = pNode.getChildList();
int addChildCount = 0;
for (TreeNode treeNode : childList) {
displayNodes.add(startIndex + addChildCount++, treeNode);
if (treeNode.isExpand()) {
addChildCount += addChildNodes(treeNode, startIndex + addChildCount);
}
}
if (!pNode.isExpand())
pNode.toggle();
return addChildCount;
}
private int removeChildNodes(TreeNode pNode) {
return removeChildNodes(pNode, true);
}
private int removeChildNodes(TreeNode pNode, boolean shouldToggle) {
if (pNode.isLeaf())
return 0;
List<TreeNode> childList = pNode.getChildList();
int removeChildCount = childList.size();
displayNodes.removeAll(childList);
for (TreeNode child : childList) {
if (child.isExpand()) {
if (toCollapseChild)
child.toggle();
removeChildCount += removeChildNodes(child, false);
}
}
if (shouldToggle)
pNode.toggle();
return removeChildCount;
}
@Override
public int getItemCount() {
return displayNodes == null ? 0 : displayNodes.size();
}
public void setPadding(int padding) {
this.padding = padding;
}
public void ifCollapseChildWhileCollapseParent(boolean toCollapseChild) {
this.toCollapseChild = toCollapseChild;
}
public void setOnTreeNodeListener(OnTreeNodeListener onTreeNodeListener) {
this.onTreeNodeListener = onTreeNodeListener;
}
public interface OnTreeNodeListener {
/**
* called when TreeNodes were clicked.
* @return weather consume the click event.
*/
boolean onClick(TreeNode node, RecyclerView.ViewHolder holder);
/**
* called when TreeNodes were toggle.
* @param isExpand the status of TreeNodes after being toggled.
*/
void onToggle(boolean isExpand, RecyclerView.ViewHolder holder);
}
public void refresh(List<TreeNode> treeNodes) {
displayNodes.clear();
findDisplayNodes(treeNodes);
notifyDataSetChanged();
}
public Iterator<TreeNode> getDisplayNodesIterator() {
return displayNodes.iterator();
}
private void notifyDiff(final List<TreeNode> temp) {
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DiffUtil.Callback() {
@Override
public int getOldListSize() {
return temp.size();
}
@Override
public int getNewListSize() {
return displayNodes.size();
}
// judge if the same items
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return TreeViewAdapter.this.areItemsTheSame(temp.get(oldItemPosition), displayNodes.get(newItemPosition));
}
// if they are the same items, whether the contents has bean changed.
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
return TreeViewAdapter.this.areContentsTheSame(temp.get(oldItemPosition), displayNodes.get(newItemPosition));
}
@Nullable
@Override
public Object getChangePayload(int oldItemPosition, int newItemPosition) {
return TreeViewAdapter.this.getChangePayload(temp.get(oldItemPosition), displayNodes.get(newItemPosition));
}
});
diffResult.dispatchUpdatesTo(this);
}
private Object getChangePayload(TreeNode oldNode, TreeNode newNode) {
Bundle diffBundle = new Bundle();
if (newNode.isExpand() != oldNode.isExpand()) {
diffBundle.putBoolean(KEY_IS_EXPAND, newNode.isExpand());
}
if (diffBundle.size() == 0)
return null;
return diffBundle;
}
// For DiffUtil, if they are the same items, whether the contents has bean changed.
private boolean areContentsTheSame(TreeNode oldNode, TreeNode newNode) {
return oldNode.getContent() != null && oldNode.getContent().equals(newNode.getContent())
&& oldNode.isExpand() == newNode.isExpand();
}
// judge if the same item for DiffUtil
private boolean areItemsTheSame(TreeNode oldNode, TreeNode newNode) {
return oldNode.getContent() != null && oldNode.getContent().equals(newNode.getContent());
}
/**
* collapse all root nodes.
*/
public void collapseAll() {
// Back up the nodes are displaying.
List<TreeNode> temp = backupDisplayNodes();
//find all root nodes.
List<TreeNode> roots = new ArrayList<>();
for (TreeNode displayNode : displayNodes) {
if (displayNode.isRoot())
roots.add(displayNode);
}
//Close all root nodes.
for (TreeNode root : roots) {
if (root.isExpand())
removeChildNodes(root);
}
notifyDiff(temp);
}
@NonNull
private List<TreeNode> backupDisplayNodes() {
List<TreeNode> temp = new ArrayList<>();
for (TreeNode displayNode : displayNodes) {
try {
temp.add(displayNode.clone());
} catch (CloneNotSupportedException e) {
temp.add(displayNode);
}
}
return temp;
}
public void collapseNode(TreeNode pNode) {
List<TreeNode> temp = backupDisplayNodes();
removeChildNodes(pNode);
notifyDiff(temp);
}
public void collapseBrotherNode(TreeNode pNode) {
List<TreeNode> temp = backupDisplayNodes();
if (pNode.isRoot()) {
List<TreeNode> roots = new ArrayList<>();
for (TreeNode displayNode : displayNodes) {
if (displayNode.isRoot())
roots.add(displayNode);
}
//Close all root nodes.
for (TreeNode root : roots) {
if (root.isExpand() && !root.equals(pNode))
removeChildNodes(root);
}
} else {
TreeNode parent = pNode.getParent();
if (parent == null)
return;
List<TreeNode> childList = parent.getChildList();
for (TreeNode node : childList) {
if (node.equals(pNode) || !node.isExpand())
continue;
removeChildNodes(node);
}
}
notifyDiff(temp);
}
}

View File

@@ -0,0 +1,23 @@
package de.sebse.fuplanner.tools.ui.treeview;
import android.support.annotation.IdRes;
import android.support.v7.widget.RecyclerView;
import android.view.View;
public abstract class TreeViewBinder<VH extends RecyclerView.ViewHolder> implements LayoutItemType {
public abstract VH provideViewHolder(View itemView);
public abstract void bindView(VH holder, int position, TreeNode node);
public static class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View rootView) {
super(rootView);
}
protected <T extends View> T findViewById(@IdRes int id) {
return (T) itemView.findViewById(id);
}
}
}

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools">
<ImageView
android:id="@+id/iv_arrow"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_keyboard_arrow_right_black_18dp" />
<TextView
android:id="@+id/tv_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:drawableLeft="@drawable/ic_folder_light_blue_700_24dp"
android:drawablePadding="10dp"
android:gravity="center_vertical"
tools:text="@string/app_name"
android:textSize="18sp" />
</LinearLayout>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools">
<TextView
android:id="@+id/tv_name"
android:layout_marginLeft="23dp"
android:drawableLeft="@drawable/ic_insert_drive_file_light_blue_700_24dp"
android:drawablePadding="10dp"
android:gravity="center_vertical"
tools:text="@string/app_name"
android:textSize="18sp"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>