Turn:
Android fully conforms to the rules, but the troublesome Jason is mapped into a tree structured and collapsible list?
Article catalogue
-
- Effect drawing first
- preface
-
- Layer by layer addView mode
Effect drawing first
preface
A friend asked me a few days ago how to implement a tree list according to a Json parsing that fully conforms to the rules but has a headache. See the format below. For some Android developers, this Json may not be friendly and there is no way to directly convert it into an entity class. In fact, it is not difficult to map this string of Json parsing into a collapsible list!
Code submitted to Github: https://github.com/ThirdGoddess/AndroidTree
{ "code":"200", "message":"success", "data":[ { "id":"1001", "title":"No. 1", "next":[ { "id":"10011", "title":"No. 1-1" }, { "id":"10012", "title":"No. 1-2", "next":[ { "id":"100121", "title":"No. 1-2-1", "next":[ { "id":"1001211", "title":"No. 1-2-1-1" }, { "id":"1001212", "title":"No. 1-2-1-2" }, { "id":"1001213", "title":"No. 1-2-1-3" }, { "id":"1001214", "title":"No. 1-2-1-4" }, { "id":"1001215", "title":"No. 1-2-1-5" } ] }, { "id":"100122", "title":"No. 1-2-2" }, { "id":"100123", "title":"No. 1-2-3", "next":[ { "id":"1001231", "title":"No. 1-2-3-1" }, { "id":"1001232", "title":"No. 1-2-3-2" }, { "id":"1001233", "title":"No. 1-2-3-3" }, { "id":"1001234", "title":"No. 1-2-3-4" }, { "id":"1001235", "title":"No. 1-2-3-5" } ] } ] }, { "id":"10013", "title":"No. 1-3" } ] }, { "id":"1002", "title":"No. 2" }, { "id":"1003", "title":"No. 3" }, { "id":"1004", "title":"No. 4", "next":[ { "id":"10041", "title":"No. 4-1" }, { "id":"10042", "title":"No. 4-2" } ] }, { "id":"1005", "title":"No. 5" } ] }
What should Jason think when he gets this string of uncertain levels? With what to analyze? What controls should I use?
Layer by layer addView mode
In fact, Gson can be directly used for parsing, but this entity class should be written by itself:
package com.example.myapplication; import java.util.List; public class DataBean { private String code; private String message; private List<Data> data; public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public List<Data> getData() { return data; } public void setData(List<Data> data) { this.data = data; } public static class Data { private String id; private String title; private List<Data> next;//The point is here public String getId() { return id; } public void setId(String id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public List<Data> getNext() { return next; } public void setNext(List<Data> next) { this.next = next; } } }
(OpenParam.json is the JSON string)
Parse using Gson:
Kotlin:
val dataBean = Gson().fromJson(OpenParam.json, DataBean().javaClass)
Java:
DataBean dataBean = new Gson().fromJson(OpenParam.json, DataBean.class)
Now that it has been resolved, it can be implemented by passing back gradually addView(), and judge whether the next field is null! But before recursion starts, analyze the layout!
Since you want to nest level by level, first come to a LinearLayout. Of course, this list is slidable. Just nest a ScrollView in the outer layer. The Activity layout is like this:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <ScrollView android:layout_width="match_parent" android:layout_height="wrap_content" tools:ignore="MissingConstraints"> <LinearLayout android:id="@+id/treeLayout" android:layout_width="match_parent" android:orientation="vertical" android:layout_height="wrap_content"> LinearLayout> ScrollView> androidx.constraintlayout.widget.ConstraintLayout>
After analyzing each item, there are two cases: one is the item with layout, and the other is the item without layout. When there is nesting, that is, there is a next field, you can use the item with layout, and vice versa! Then the two layouts are as follows:
With layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageView android:id="@+id/flag" android:layout_width="40dp" android:layout_height="40dp" android:layout_marginLeft="32dp" android:padding="8dp" android:src="@mipmap/open" /> <TextView android:id="@+id/title" android:layout_width="0dp" android:layout_height="40dp" android:layout_marginTop="1dp" android:layout_weight="1" android:gravity="center_vertical" android:paddingRight="32dp" android:textColor="#333333" /> LinearLayout> <LinearLayout android:id="@+id/nextLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="32dp" android:orientation="vertical" /> LinearLayout>
Without layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/info" android:layout_width="match_parent" android:layout_height="40dp" android:layout_marginLeft="72dp" android:layout_marginRight="32dp" android:gravity="center_vertical" android:textColor="#333333" /> LinearLayout>
After that, it will be implemented recursively according to the entity class, loop through, judge whether there is a next field, and make two cases, such as the code between lines 37 and 69! If there are sub nodes, use the item with sub layout; otherwise, use another one!
package com.example.myapplication import android.animation.ObjectAnimator import android.os.Bundle import android.view.LayoutInflater.from import android.view.View import android.widget.LinearLayout import androidx.appcompat.app.AppCompatActivity import androidx.core.view.isGone import com.google.gson.Gson import kotlinx.android.synthetic.main.activity_main.* import kotlinx.android.synthetic.main.item_text.view.* import kotlinx.android.synthetic.main.item_tree.view.* class MainActivity : AppCompatActivity() { lateinit var objectAnimator: ObjectAnimator override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) //Parse Jason val dataBean = Gson().fromJson(OpenParam.json, DataBean().javaClass) //Create View createView(dataBean.data, treeLayout) } /** * Create layout recursively */ private fun createView(dataList: MutableList<DataBean.Data>, linearLayout: LinearLayout) { for (i in 0 until dataList.size) { val title = dataList[i].title val next = dataList[i].next if (null != next) { val childLayout = from(this).inflate(R.layout.item_tree, null, false) childLayout.title.text = title //Expand and close click events childLayout.title.setOnClickListener { if (childLayout.nextLayout.isGone) { //open childLayout.nextLayout.visibility = View.VISIBLE //Add points to expand animation objectAnimator = ObjectAnimator.ofFloat(childLayout.flag, "rotation", 0f) objectAnimator.duration = 400 objectAnimator.start() } else { //hide childLayout.nextLayout.visibility = View.GONE //Add point to close animation objectAnimator = ObjectAnimator.ofFloat(childLayout.flag, "rotation", -90f) objectAnimator.duration = 400 objectAnimator.start() } } createView(next, childLayout.nextLayout) linearLayout.addView(childLayout) } else { val textLayout = from(this).inflate(R.layout.item_text, null, false) textLayout.info.text = title linearLayout.addView(textLayout) } } } }
In this way, this is applicable to the conventional folding list. If you need to load more, you can directly judge whether the ScrollView scrolls to the bottom and whether the last network loading is completed. If the conditions are met, you can call 27 lines of code again for insertion! No more explanations here. Friends who don't understand can ask me directly in the comment area!
Turn:
Android fully conforms to the rules, but the troublesome Jason is mapped into a tree structured and collapsible list?
--Posted from Rpc