如何在Xamarin Android中修改TreeNode的前景色
Hey there! Let's tackle this problem together. You've got your TreeView up and running, and you can already adjust the text color for your TreeItem nodes using your custom MyHolder—nice work! Now, for those parent/child nodes like parent2 and Child1 that you created directly with string values, here's how you can modify their text color or the foreground color of their underlying LinearLayout.
The Root of the Issue
When you create a TreeNode with a string (like new TreeNode("parent2")), the TreeView uses its default DefaultNodeViewHolder instead of your custom MyHolder. This default view holder uses a built-in layout with a TextView (and a LinearLayout as the root), so we need to either override this default behavior or modify the views directly.
Solution 1: Custom ViewHolder for String Nodes
The simplest way is to create a custom view holder for string-type nodes, just like you did for TreeItem. This lets you control the text color and LinearLayout foreground explicitly.
First, add this custom view holder class to your project:
public class StringNodeHolder : DefaultNodeViewHolder { public StringNodeHolder(Context context) : base(context) { } public override void BindNode(TreeNode node) { base.BindNode(node); // 1. Modify the text color of the node's text var textView = (TextView)View.FindViewById(Resource.Id.node_value); textView.SetTextColor(Android.Graphics.Color.DarkBlue); // Replace with your desired color // 2. Modify the foreground color of the root LinearLayout var rootLayout = (LinearLayout)View; rootLayout.SetForeground(new ColorDrawable(Android.Graphics.Color.LightGray)); // Adjust as needed } }
Then, update your node creation code to use this holder for your string nodes:
// Create root node TreeNode root = TreeNode.InvokeRoot(); // Use custom holder for parent node TreeNode parent = new TreeNode("parent2").SetViewHolder(new StringNodeHolder(this)); // Use custom holder for child1 node TreeNode child1 = new TreeNode("Child1").SetViewHolder(new StringNodeHolder(this)); // Rest of your node creation code remains the same... TreeItem item = new TreeItem() { text = " Level1" }; TreeNode child10 = new TreeNode(item).SetViewHolder(new MyHolder(this)); child1.AddChild(child10); // ...
Solution 2: Global Default ViewHolder (No Per-Node Setup)
If you want all string-type nodes to automatically use your custom styling without setting the holder for each one, you can override the TreeView's default view holder factory:
// After creating your AndroidTreeView instance AndroidTreeView atv = new AndroidTreeView(this, root); // Set a custom factory to handle string nodes atv.DefaultViewHolderFactory = new DefaultViewHolderFactoryDelegate((context, node) => { if (node.Value is string) { return new StringNodeHolder(context); } // Fall back to default holder for other node types return new DefaultNodeViewHolder(context); }); // Add the TreeView to your layout as before LinearLayout rootlayout = FindViewById<LinearLayout>(Resource.Id.rootlayout); rootlayout.AddView(atv.View); rootlayout.Invalidate();
This way, every string-based node will use your StringNodeHolder automatically, keeping your code clean and consistent.
Key Notes
- The default
DefaultNodeViewHolderuses a TextView with the IDnode_value—that's why we can access it directly in the custom holder. - When modifying the LinearLayout's foreground, you can use any
Drawable(not justColorDrawable) if you want more complex effects like ripple animations.
内容的提问来源于stack exchange,提问作者Rachel

