我在飞镖课上上课
//FOR DESIGN
private Toolbar toolbar;
private DrawerLayout drawerLayout;
private NavigationView navigationView;
//FOR FRAGMENTS
private Fragment fragmentIntro;
private Fragment fragmentPhoto;
private Fragment fragmentProfile;
private Fragment fragmentDossier;
private Fragment fragmentDate;
private Fragment fragmentZone;
private Fragment fragmentTypeIntervention;
//FOR DATAS
private static final int FRAGMENT_INTRO = 0;
private static final int FRAGMENT_PHOTO = 1;
private static final int FRAGMENT_PROFILE = 2;
private static final int FRAGMENT_DOSSIER = 3;
private static final int FRAGMENT_DATE = 4;
private static final int FRAGMENT_ZONE = 5;
private static final int FRAGMENT_TYPE_INTERVENTION = 6;
// FOR STRINGS
private static TextView mFragmentPageNewsTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Configure all views
this.configureToolBar();
this.configureDrawerLayout();
this.configureNavigationView();
// Show First Fragment
this.showFirstFragment();
}
@Override
public void onBackPressed() {
// Handle back click to close menu
if (this.drawerLayout.isDrawerOpen(GravityCompat.START)) {
this.drawerLayout.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@Override
public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
// Show fragment after user clicked on a menu item
switch (id){
case R.id.activity_main_drawer_intro :
this.showFragment(FRAGMENT_INTRO);
break;
case R.id.activity_main_drawer_photo :
this.showFragment(FRAGMENT_PHOTO);
break;
case R.id.activity_main_drawer_profile:
this.showFragment(FRAGMENT_PROFILE);
break;
case R.id.activity_main_drawer_dossier:
this.showFragment(FRAGMENT_DOSSIER);
break;
case R.id.activity_main_drawer_date:
this.showFragment(FRAGMENT_DATE);
break;
case R.id.activity_main_drawer_zone:
this.showFragment(FRAGMENT_ZONE);
break;
case R.id.activity_main_drawer_typeintervention:
this.showFragment(FRAGMENT_TYPE_INTERVENTION);
break;
default:
break;
}
this.drawerLayout.closeDrawer(GravityCompat.START);
return true;
}
// ---------------------
// CONFIGURATION
// ---------------------
// Configure Toolbar
private void configureToolBar(){
this.toolbar = (Toolbar) findViewById(R.id.activity_main_toolbar);
setSupportActionBar(toolbar);
}
// Configure Drawer Layout
private void configureDrawerLayout(){
this.drawerLayout = (DrawerLayout) findViewById(R.id.activity_main_drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawerLayout.addDrawerListener(toggle);
toggle.syncState();
}
// Configure NavigationView
private void configureNavigationView(){
this.navigationView = (NavigationView) findViewById(R.id.activity_main_nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
// ---------------------
// FRAGMENTS
// ---------------------
// Show first fragment when activity is created
private void showFirstFragment(){
Fragment visibleFragment = getSupportFragmentManager().findFragmentById(R.id.activity_main_frame_layout);
if (visibleFragment == null){
// Show Photo Fragment
this.showFragment(FRAGMENT_INTRO);
// Mark as selected the menu item corresponding to PhotoFragment
this.navigationView.getMenu().getItem(0).setChecked(true);
}
}
// Show fragment according an Identifier
private void showFragment(int fragmentIdentifier){
switch (fragmentIdentifier){
case FRAGMENT_INTRO :
this.showIntroFragment();
break;
case FRAGMENT_PHOTO :
this.showPhotoFragment();
break;
case FRAGMENT_PROFILE:
this.showProfileFragment();
break;
case FRAGMENT_DOSSIER:
this.showClientsFragment();
break;
case FRAGMENT_DATE:
this.showDateFragment();
break;
case FRAGMENT_ZONE:
this.showZoneFragment();
break;
case FRAGMENT_TYPE_INTERVENTION:
this.showTypeInterventionFragment();
break;
default:
break;
}
}
// ---
// Create each fragment page and show it
private void showIntroFragment() {
if (this.fragmentIntro == null) this.fragmentIntro = IntroFragment.newInstance();
this.startTransactionFragment(this.fragmentIntro);
}
private void showPhotoFragment(){
if (this.fragmentPhoto == null) this.fragmentPhoto = PhotoFragment.newInstance();
this.startTransactionFragment(this.fragmentPhoto);
}
private void showClientsFragment(){
if (this.fragmentDossier == null) this.fragmentDossier = DossierFragment.newInstance();
this.startTransactionFragment(this.fragmentDossier);
}
private void showProfileFragment(){
if (this.fragmentProfile == null) this.fragmentProfile = ProfileFragment.newInstance();
this.startTransactionFragment(this.fragmentProfile);
}
private void showDateFragment(){
if (this.fragmentDate == null) this.fragmentDate = DateFragment.newInstance();
this.startTransactionFragment(this.fragmentDate);
}
private void showZoneFragment(){
if (this.fragmentZone == null) this.fragmentZone = ZoneFragment.newInstance();
this.startTransactionFragment(this.fragmentZone);
}
private void showTypeInterventionFragment(){
if (this.fragmentTypeIntervention == null) this.fragmentTypeIntervention = TypeInterventionFragment.newInstance();
this.startTransactionFragment(this.fragmentTypeIntervention);
}
// ---
// Generic method that will replace and show a fragment inside the MainActivity Frame Layout
private void startTransactionFragment(Fragment fragment){
if (!fragment.isVisible()){
getSupportFragmentManager().beginTransaction()
.replace(R.id.activity_main_frame_layout, fragment).commit();
}
}
我从api接收的数据在单个数组中返回所有注释(无论处于什么级别)。 parentCommentId用于指向答复的父级。要将这些数据转换为嵌套结构,
class PostComment {
int id;
int title;
int parentCommentId;
List<PostComment> replies;
}
使用此代码,我在下面的结构中获得了注释数组。
void toNestedComments({List<PostComment> comments}) {
comments.forEach((postComment) {
if (postComment.parentCommentId != null) {
PostComment parentComment = comments.firstWhere((comment) => comment.id == postComment.parentCommentId, orElse: () => null);
parentComment.replies.add(postComment);
}
});
comments.removeWhere((c) => c.parentCommentId != null);
}
但是,UI要求数据显示如下。
Post 1
- Post 11
- Post 12
- Post 121
- Post 122
- Post 13
Post 2
- Post 21
- Post 211
您会建议对上述功能进行哪些修改以实现上述结构?
当前代码和数据结构位于https://dartpad.dartlang.org/6231828b3ea9dc1e956e87353394dae7
答案 0 :(得分:0)
我不确定您的数据结构,但我想您可以执行以下操作:
像这样扩展PostComment类:
class PostComment {
int id;
int title;
int parentCommentId;
List<PostComment> replies = [];
Iterable<PostComment> thisAndNestedReplies() sync* {
yield this;
for (var reply in replies) {
yield* reply.thisAndNestedReplies();
}
}
}
然后您可以执行以下操作(我仍在使用您的方法来获取嵌套的数据结构):
toNestedComments(comments: comments);
var newList = comments
.where((postComment) => postComment.parentCommentId == null)
.expand((postComment) => postComment.thisAndNestedReplies()).toList();
答案 1 :(得分:-1)
在PostComment
实体中没有任何业务逻辑的解决方案。
数据查询中的所有逻辑都在函数main
中。
import 'package:queries/collections.dart';
import 'dart:core';
import 'dart:convert';
void main() {
var comments = Collection(getComments());
var query = comments
.groupJoin(
comments,
(o) => o.id,
(i) => i.parentCommentId,
(o, i) =>
o..comments.addAll((i as IEnumerable<PostComment>).toList()))
.where((p) => p.parentCommentId == null);
printComments(query.toList(), 0);
}
void printComments(List<PostComment> comments, int indent) {
for (var comment in comments) {
var sb = StringBuffer();
sb.write(''.padLeft(indent, ' '));
sb.write(comment.id);
print(sb);
printComments(comment.comments, indent + 1);
}
}
// Json with the all the comments. Replies to comment have parentCommentId set.
String json = '''
{
"comments": [
{
"id": 35,
"description": "Post 1",
"parentCommentId": null
},
{
"id": 36,
"description": "Post 11",
"parentCommentId": 35
},
{
"id": 37,
"description": "Post 111",
"parentCommentId": 36
},
{
"id": 38,
"description": "Post 2",
"parentCommentId": null
},
{
"id": 39,
"description": "Post 3",
"parentCommentId": null
},
{
"id": 61,
"description": "Post 2",
"parentCommentId": 35
},
{
"id": 62,
"description": "Post 21",
"parentCommentId": 61
},
{
"id": 64,
"description": "Post 211",
"parentCommentId": 62
}
]
}
''';
List<PostComment> getComments() {
var comments = <PostComment>[];
final responseMap = jsonDecode(json);
responseMap['comments'].forEach((i) {
comments.add(PostComment.fromJson(i));
});
return comments;
}
class PostComment {
PostComment({this.id, this.description, this.parentCommentId, this.postId});
int id;
String description;
int parentCommentId;
int postId;
List<PostComment> comments;
factory PostComment.fromJson(Map<String, dynamic> map) {
final commentInfo = map;
final _comment = PostComment(
id: commentInfo['id'],
description: commentInfo['description'],
postId: commentInfo['postId'],
parentCommentId: int.tryParse(commentInfo['parentCommentId'].toString()),
);
_comment.comments = List<PostComment>();
return _comment;
}
String toString() {
return this.description;
}
}
结果:
35
36
37
61
62
64
38
39
PS
使用此代码i as IEnumerable<PostComment>
是因为当前Dart编译器无法推断数据类型。看起来像编译器中的错误。