为什么我的 RecyclerView 渲染在对话框窗口中而不是在主布局中?

问题描述 投票:0回答:1

我的应用程序创建以下布局:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    activity = this;
    try {
        setContentView(R.layout.main);
    } catch (RuntimeException ex) {
        ex.printStackTrace();
        Toast.makeText(activity, getString(R.string.install_from_google_play), Toast.LENGTH_LONG).show();
        finish();
        return;
    }

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/webv"
android:layout_width="match_parent"
android:layout_height="match_parent">

<WebView
    android:id="@+id/browser_page"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

<TextView
    android:id="@+id/title"
    android:text="@string/comments_page"
    android:textStyle="bold"
    android:textSize="22sp"
    android:gravity="center_horizontal"
    android:layout_below="@id/browser_page"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/user_view"
    android:background="@null"
    android:layout_margin="10dp"
    android:listSelector="@android:color/darker_gray"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@id/title" />

<ProgressBar
    android:id="@+id/retrievedCommentsProgressBar"
    style="?android:attr/progressBarStyleLarge"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="invisible"
    android:indeterminate="true"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"/>

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recent_comments_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginStart="10dp"
    android:layout_marginTop="10dp"
    android:layout_marginEnd="10dp"
    android:layout_marginBottom="10dp"
    android:background="@null"
    android:listSelector="@android:color/darker_gray"
    android:visibility="invisible" />

<com.chiaramail.opencomments.MovableFloatingActionButton
   android:id="@+id/add_comment"
   android:visibility="visible"
   app:fabSize="normal"
   app:srcCompat="@drawable/plus_circle"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_marginStart="100dp"
   android:layout_marginTop="50dp"
   android:layout_marginEnd="10dp"
   android:layout_alignParentEnd="true"
   android:layout_centerHorizontal="true" />

<com.chiaramail.opencomments.MovableFloatingActionButton
    android:id="@+id/return_to_list"
    android:visibility="invisible"
    app:fabSize="normal"
    app:srcCompat="@drawable/view_list_outline"
    android:layout_below="@+id/add_comment"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="100dp"
    android:layout_marginTop="50dp"
    android:layout_marginEnd="10dp"
    android:layout_alignParentEnd="true"
    android:layout_centerHorizontal="true" />

<Button
    android:id="@+id/refresh"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:visibility="gone"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/refresh" />

<ImageView
    android:id="@+id/back"
    android:layout_alignParentBottom="true"
    android:layout_alignParentStart="true"
    android:layout_margin="10dp"
    android:layout_width="50dp"
    android:layout_height="50dp"
    app:srcCompat="@drawable/chevron_left_disabled" />

<ImageView
    android:id="@+id/forward"
    android:layout_alignParentBottom="true"
    android:layout_alignParentEnd="true"
    android:layout_margin="10dp"
    android:layout_width="50dp"
    android:layout_height="50dp"
    app:srcCompat="@drawable/chevron_right_disabled" />

<ProgressBar
    android:id="@+id/progressBar"
    style="?android:attr/progressBarStyleLarge"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="invisible"
    android:indeterminate="true"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"/>

</RelativeLayout>

我在 onCreate() 中声明以下 RecyclerView:

    final ArrayList<UserComments> pageItemList = new ArrayList<>();

    itemArrayAdapter = new CommentsAdapter(this, activity, pageItemList);
    user_view = findViewById(R.id.user_view);
    user_view.setAdapter(itemArrayAdapter);
    user_view.addItemDecoration(new DividerItemDecoration(activity,
            DividerItemDecoration.VERTICAL));
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
    user_view.setLayoutManager(linearLayoutManager);

代码最终调用方法 fetchComments() 将数据加载到 pageItemList 中。

获取评论():

    private void fetchComments(String url) {
    String extractedURL = extractSite(url);
    spinner.setVisibility(View.VISIBLE);
    String extractedSite = extractSite(url);
    String extractedDomain = extractDomain(url);
    // If the URL doesn't have a host name, e.g., example.com, add "www." to the url and look for
    // comments for either one.
    if (extractedSite.equals(extractedDomain)) extractedSite = "www." + extractedDomain;
    String mobileSite = "m." + extractedDomain;
    Query commentQuery = baseRef.whereIn(FSHOSTNAME, Arrays.asList(extractedSite, mobileSite, extractedDomain));

    registration = commentQuery.addSnapshotListener(new EventListener<QuerySnapshot>() {
        @Override
        public void onEvent(@Nullable QuerySnapshot value,
                            @Nullable FirebaseFirestoreException e) {
            if (mFirebaseUser == null || value.size() == 0) {
                if (blacklistArray.contains(extractDomain(url))) {
                    mActionBar.setBackgroundDrawable(new ColorDrawable(redToolbarColor));
                    showScamWarning(url);
                    retrieved_comments_dialog.show();
                }
                spinner.setVisibility(View.INVISIBLE);
                return;
            }
            if (e != null) {
                Log.w(TAG, "Listen failed.", e);
                Toast.makeText(activity, "user_ID = " + user_ID, Toast.LENGTH_LONG).show();
                Toast.makeText(activity, getString(R.string.listen_error) + BLANK + e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
                spinner.setVisibility(View.INVISIBLE);
                return;
            }

            // Display the "Loading comments..." message the first time only.
            if (!registrations.containsKey(url)) Toast.makeText(activity, getString(R.string.loading_comments), Toast.LENGTH_SHORT).show();
            boolean isEmpty = true;
            ArrayList tmp = (ArrayList) docRefList.clone();
            docRefList.clear();
            userDocList.clear();
            pageURLList.clear();
            pageItemList.clear();
            for (QueryDocumentSnapshot doc : value) {
                if (!isSamePage(doc, url)) continue;
                // Don't include duplicates.
                for (int i = 0; i < tmp.size(); i++) {
                    if (!((QueryDocumentSnapshot)tmp.get(i)).getId().equals(doc.getId()) &&
                            !docRefList.contains(doc)) {
                        isEmpty = false;
                        getUserValuesForPage(doc);
                    }
                }
                if (tmp.size() == 0) {
                    isEmpty = false;
                    getUserValuesForPage(doc);
                }

            }

            // Unregister the existing listener, if any.
            if (registrations.containsKey(url)) registrations.remove(url);
            registrations.put(url, registration);
            if (isEmpty) {
                mActionBar.setBackgroundDrawable(new ColorDrawable(defaultColor));
                color_map.put(url, defaultColor);
                pageItemList.clear();
                itemArrayAdapter.notifyDataSetChanged();
                spinner.setVisibility(View.INVISIBLE);
            } else {
                if (blacklistArray.contains(extractDomain(url))) {
                    mActionBar.setBackgroundDrawable(new ColorDrawable(redToolbarColor));
                    showScamWarning(url);
                    retrieved_comments_dialog.show();
                } else {
                    // If the current page is not a search page and not a tap on the search bar, show the prompt and the green header.
                    if (!url.contains(SEARCH_PARAM)) {
                        mActionBar.setBackgroundDrawable(new ColorDrawable(greenToolbarColor));
                        color_map.put(url, greenToolbarColor);
                    } else {
                        mActionBar.setBackgroundDrawable(new ColorDrawable(defaultColor));
                        color_map.put(url, defaultColor);
                        pageItemList.clear();
                        itemArrayAdapter.notifyDataSetChanged();
                    }
                }
            }
        }
    });
}

getUserValuesForPage():

    private void getUserValuesForPage(DocumentSnapshot doc) {
    DocumentReference mOtherUserDocRef = db.collection(USERS).document((String)doc.get(FSUSERID));
    docRefList.add(doc);
    mOtherUserDocRef.get(Source.SERVER).addOnCompleteListener((OnCompleteListener<DocumentSnapshot>) task -> {
        //          mUserDocRef.get(Source.SERVER).addOnCompleteListener((OnCompleteListener<DocumentSnapshot>) task -> {
        if (task.isSuccessful()) {
            DocumentSnapshot userDoc = task.getResult();
            showComment(pageItemList, itemArrayAdapter,(String)doc.getId(), (String)doc.get(FSUSERID), (String)doc.get(FSCOMMENT), (String)doc.get(FSPATH), (HashMap<String, String>)doc.get(FSSEARCH), (String)doc.get(FSSUBJECT), (Timestamp) doc.get(FSTIMESTAMP), (String)doc.get(FSURL), false, (String)userDoc.get(FSDEVICEID), (String)userDoc.get(FSNAME), (String)userDoc.get(FSPICTUREURL), (String)doc.get(FSREPLY));
        } else {
            Toast.makeText(context, getString(R.string.getuser_error) + BLANK + Objects.requireNonNull(task.getException()).getMessage(), Toast.LENGTH_LONG);
            crashlytics.log(context.getString(R.string.getuser_error) + BLANK + Objects.requireNonNull(task.getException()).getMessage());
            crashlytics.log("User ID: " + doc.get(FSUSERID));
        }
    });
}

显示评论():

    private void showComment(ArrayList<UserComments> itemList, 
      RecyclerView.Adapter adapter, String docID, String uid, String comment, 
      String path, HashMap<String, String> search, String subject, Timestamp 
      timestamp, String url, boolean scam_warning, String devid, String uname, 
      String photoURL, String reply ) {
    UserComments nextComment = new UserComments();
    nextComment.user_name = (uname != null ? uname : 
      getString(R.string.anon_person));
    nextComment.device_id = devid;
    nextComment.picture = (photoURL != null ? photoURL : SILHOUETTE_URL);
    nextComment.timestamp = timestamp;
    nextComment.subject = subject;
    nextComment.docId = docID;
    nextComment.reply = reply;
    nextComment.userId = uid;
    nextComment.comment = comment;
    nextComment.site = extractSite(url);
    nextComment.page_url = url;
    nextComment.scam_warning = scam_warning;
    nextComment.path = path;
    nextComment.search = search;
    if (!commentsStack.contains(nextComment)) commentsStack.add(nextComment);
    itemList.add(commentsStack.pop());
    if (showList) {
        if (!recentCommentsShown) {
            recentCommentsSpinner.setVisibility(View.VISIBLE);
            return_to_list.setVisibility(View.INVISIBLE);
            recent_comments_dialog.show();
        }
        recentCommentsShown = true;
        showList = false;
    }
    Collections.sort(itemList, new SortByTime().reversed());
    adapter.notifyDataSetChanged();
    spinner.setVisibility(View.INVISIBLE);
    recentCommentsSpinner.setVisibility(View.INVISIBLE);
}

UserComments.java:

public class UserComments {
Timestamp timestamp;
String  hostname;
String  path;
String  page_url;
boolean  scam_warning;
String  userUID;
String device_id;
String picture;
String docId;
String replyDocID;
String user_name;
String subject;
String reply;
String userId;
String comment;
String site;
Map     search;
}

我创建一个AlertDialog如下:

    private void createRetrievedCommentsDialog(ArrayList<UserComments> list) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    View dialoglayout = getLayoutInflater().inflate(R.layout.retrieved_comments, null);
    retrievedCommentsSpinner = dialoglayout.findViewById(R.id.retrievedCommentsProgressBar);
    RecyclerView view = dialoglayout.findViewById(R.id.user_view);

    itemArrayAdapter = new CommentsAdapter(this, activity, list);
    view.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
    view.setAdapter(itemArrayAdapter);
    builder
            .setView(dialoglayout)
            .setCancelable(false)
            .setNeutralButton(context.getString(R.string.dismiss), new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    dialog.dismiss();
                }
            });
    retrieved_comments_dialog = builder.create();
    spinner.setVisibility(View.INVISIBLE);
}

该应用程序使用布尔值 autoshowComments 来控制屏幕是否应垂直分割为两部分,一个显示 WebView,另一个显示显示一堆数据的 RecyclerView:当 autoshowComments 为 true 时,屏幕被分割并显示数据被展示。我面临的问题是,如果在应用程序启动时将布尔值设置为 true,则尽管屏幕按预期分割,但数据不会显示在 WebView 下方。此外,如果我以 autoshowComments false 启动应用程序,然后使用菜单项将其更改为 true,

    public boolean onPrepareOptionsMenu(Menu menu) {
    menu.findItem(R.id.overlay_menu).setChecked(autoshowComments);
    return super.onPrepareOptionsMenu(menu);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main_menu, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == R.id.overlay_menu) {
        ViewGroup.LayoutParams params = browser_page.getLayoutParams();
        if (item.isChecked()) {
            item.setChecked(false);
            user_view.setVisibility(View.GONE);
            params.height = metrics.heightPixels;
            browser_page.setLayoutParams(params);
            autoshowComments = false;
        } else {
            item.setChecked(true);
            user_view.setVisibility(View.VISIBLE);
            params.height = Integer.valueOf((int) (WEBVIEW_HT * metrics.heightPixels));
            browser_page.setLayoutParams(params);
            autoshowComments = true;
        }
        updateAutoshow(autoshowComments);
        return true;
    }
 }

数据项确实出现了(尽管它们没有像 fetchComments() 那样实时更新):

这是当应用程序启动且 autoshowComments 设置为 true 时屏幕的样子(“此页面的评论”下方不显示任何内容):

取消选中该框会出现以下情况(请注意,WebView 未调整大小):

当应用程序启动且 autoshowComments 设置为 false 时,我们得到:

当选中该框时:

取消选中该框后,页面将按预期调整大小。

点击绿色标题栏会显示 AlertDialog: 所以我的问题是为什么 pageItemList 在第一种情况下没有加载,但在第二种情况下加载?

android android-recyclerview
1个回答
0
投票

我认为你的问题在这里:

pageItemList.clear();
itemArrayAdapter.notifyDataSetChanged();
在调用

notifyDataSetChanged 之前,pageItemList 需要数据。当我在代码中搜索 pageItemList 时,我没有看到任何将项目添加到 pageItemList 中的行。

检查这一点

© www.soinside.com 2019 - 2024. All rights reserved.