总而言之,我正在构建一个显示以下内容的社交媒体应用:
我建立了一个自定义BaseAdapter来填充每个ListView中的一个自定义单元。 Newsfeed ListView(用于填充该帐户的所有用户的帖子)正在正确填充。
时间轴ListView(用于填充帐户中的一个配置文件的帖子)未显示。我设置了断点以确保在填充时间轴ListView时ArrayList不为null或为空。另外,断点可以验证我的自定义适配器实际上是否正在从ArrayList中提取数据并填充单元格。但是,ListView根本不可见。
这是我的新闻提要片段的布局文件(运行正常):
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorSkyPrimary">
<android.support.constraint.ConstraintLayout
android:id="@+id/constraintLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:elevation="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<EditText
android:id="@+id/input_post"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
android:backgroundTint="@color/colorSkyPrimary"
android:ems="10"
android:gravity="start|top"
android:hint="@string/what_s_going_on"
android:importantForAutofill="no"
android:inputType="textMultiLine"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:targetApi="o" />
<ImageButton
android:id="@+id/button_photo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:backgroundTint="@android:color/white"
android:contentDescription="@string/camera_button"
app:layout_constraintBottom_toBottomOf="@+id/input_post"
app:layout_constraintEnd_toEndOf="@+id/input_post"
app:srcCompat="@drawable/camera_icon" />
<Button
android:id="@+id/button_cancel"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="48dp"
android:layout_marginTop="8dp"
android:text="@android:string/cancel"
android:textColor="@color/colorGrassPrimary"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/post_image" />
<Button
android:id="@+id/button_update"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="48dp"
android:backgroundTint="@color/colorGrassPrimary"
android:text="@string/update"
android:textColor="@color/colorButtonText"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/post_image" />
<ImageView
android:id="@+id/post_image"
android:layout_width="0dp"
android:layout_height="300dp"
android:contentDescription="@string/post_image"
android:scaleType="fitCenter"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/input_post"
tools:srcCompat="@tools:sample/avatars" />
</android.support.constraint.ConstraintLayout>
<ListView
android:id="@+id/list_newsfeed"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/picker_image"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/constraintLayout"
app:layout_constraintVertical_bias="0.0" />
<android.support.constraint.ConstraintLayout
android:id="@+id/picker_image"
android:layout_width="0dp"
android:layout_height="75dp"
android:background="@android:color/white"
android:elevation="16dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<android.support.constraint.Guideline
android:id="@+id/guideline14"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
<ImageButton
android:id="@+id/button_camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="32dp"
android:layout_marginBottom="8dp"
android:background="@android:color/transparent"
android:contentDescription="@string/camera_button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline14"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/camera_icon_large" />
<ImageButton
android:id="@+id/button_gallery"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:background="@android:color/transparent"
android:contentDescription="@string/gallery_button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@+id/guideline14"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.375"
app:srcCompat="@drawable/gallery_icon" />
</android.support.constraint.ConstraintLayout>
这是我的Profile片段的布局文件(其中ListView在运行时未显示)
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorSkyPrimary">
<android.support.constraint.ConstraintLayout
android:id="@+id/constraintLayout4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:elevation="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/profile_photo"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginStart="32dp"
android:layout_marginTop="32dp"
android:src="@drawable/male_icon_large"
app:civ_border_color="@android:color/transparent"
app:civ_border_width="2dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/display_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
android:text="@string/brelynn_mack"
android:textAlignment="viewStart"
android:textColor="@color/colorTextDark"
android:textSize="18sp"
app:layout_constraintEnd_toStartOf="@+id/button_delete_profile"
app:layout_constraintStart_toEndOf="@+id/profile_photo"
app:layout_constraintTop_toTopOf="@+id/profile_photo" />
<TextView
android:id="@+id/display_timestamp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:text="@string/may_14_2019_9_59_pm"
android:textAlignment="viewStart"
android:textColor="@color/colorTextLight"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/profile_photo"
app:layout_constraintTop_toBottomOf="@+id/display_name" />
<TextView
android:id="@+id/display_last_location"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="@string/_8741_grouse_run_lane_28314"
android:textAlignment="viewStart"
android:textColor="@color/colorTextPrimary"
android:textSize="12sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/profile_photo"
app:layout_constraintTop_toBottomOf="@+id/display_timestamp" />
<ImageButton
android:id="@+id/button_delete_profile"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:background="@android:color/white"
android:contentDescription="@string/trash_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/trash_icon" />
<ImageButton
android:id="@+id/button_photo"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_marginStart="8dp"
android:layout_marginBottom="16dp"
android:background="@android:color/white"
android:contentDescription="@string/camera_button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@+id/profile_photo"
app:layout_constraintTop_toBottomOf="@+id/profile_photo"
app:srcCompat="@drawable/camera_icon" />
<ImageButton
android:id="@+id/button_family"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginBottom="8dp"
android:background="@android:color/white"
android:contentDescription="@string/family_button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:srcCompat="@drawable/family_icon_small" />
<ImageButton
android:id="@+id/button_gallery"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_marginEnd="8dp"
android:background="@android:color/transparent"
android:contentDescription="@string/gallery_button"
android:scaleType="fitCenter"
app:layout_constraintEnd_toEndOf="@+id/profile_photo"
app:layout_constraintTop_toBottomOf="@+id/profile_photo"
app:srcCompat="@drawable/gallery_icon" />
</android.support.constraint.ConstraintLayout>
<ListView
android:id="@+id/list_posts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/constraintLayout4" />
这是我的自定义适配器:
public class NewsfeedAdapter extends BaseAdapter {
// Class properties
private static final String TAG = "NewsfeedAdapter";
public static final String EXTRA_POSTS = "extra_posts";
public static final String EXTRA_POSITION = "extra_position";
private final Context context;
ArrayList<Post> posts;
Account account;
// Constructor
public NewsfeedAdapter(Context context, ArrayList<Post> posts, Account account) {
this.context = context;
this.posts = posts;
this.account = account;
}
// System generated methods
@Override
public int getCount() {
return posts.size();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public Object getItem(int position) {
return posts.get(position);
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final Post post = posts.get(position);
if(convertView == null) {
LayoutInflater layoutInflater = LayoutInflater.from(context);
convertView = layoutInflater.inflate(R.layout.cell_newsfeed, null);
}
TextView profileNameDisplay = convertView.findViewById(R.id.display_profile_name);
String name = post.getPosterName() + " " + account.getFamilyName();
profileNameDisplay.setText(name);
TextView timestampDisplay = convertView.findViewById(R.id.display_timestamp);
SimpleDateFormat dateFormat = new SimpleDateFormat("MMMM dd, yyyy @ hh:mm a", Locale.getDefault());
String timestamp = dateFormat.format(post.getTimeStamp());
timestampDisplay.setText(timestamp);
TextView postMessageDisplay = convertView.findViewById(R.id.display_post_message);
postMessageDisplay.setText(post.getPostMessage());
if (post.getHasImage()) {
AccountUtils.loadProfilePhoto(context, convertView, post.getPosterId());
}
else {
ImageView postImage = convertView.findViewById(R.id.display_post_image);
postImage.setVisibility(View.GONE);
}
PostUtils.loadPostImage(convertView, post.getPostId());
ImageButton deleteButton = convertView.findViewById(R.id.button_delete_post);
ImageButton editButton = convertView.findViewById(R.id.button_edit_post);
toggleButtons(post, editButton, deleteButton);
deleteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
alertBuilder.setTitle(context.getString(R.string.delete_post));
alertBuilder.setMessage(context.getString(R.string.delete_post_message));
alertBuilder.setPositiveButton(context.getString(R.string.delete), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
posts.remove(position);
PostUtils.deletePost(context, post.getPostId(), post.getPosterId());
notifyDataSetChanged();
PostUtils.listenForNews(context);
}
});
alertBuilder.setNegativeButton(context.getString(R.string.cancel), null);
AlertDialog alert = alertBuilder.create();
alert.show();
}
});
editButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent editIntent = new Intent(context, EditPostActivity.class);
editIntent.putExtra(EXTRA_POSTS, posts);
editIntent.putExtra(EXTRA_POSITION, position);
context.startActivity(editIntent);
}
});
return convertView;
}
// Custom methods
private void toggleButtons(Post post, ImageButton editButton, ImageButton deleteButton) {
long twoMinutes = System.currentTimeMillis() - (2 * 60 * 1000);
long fiveMinutes = System.currentTimeMillis() - (5 * 60 * 1000);
if (post.getTimeStamp().getTime() < fiveMinutes) {
editButton.setVisibility(View.GONE);
}
else {
editButton.setVisibility(View.VISIBLE);
}
if (post.getTimeStamp().getTime() < twoMinutes) {
deleteButton.setVisibility(View.GONE);
}
else {
deleteButton.setVisibility(View.VISIBLE);
}
}
以下是Newsfeed片段中用于加载我的数据并设置适配器的生命周期方法:
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_newsfeed, container, false);
PostUtils.listenForNews(getActivity());
mPosts = PostUtils.loadNewsfeed(getActivity());
mNewsfeed = view.findViewById(R.id.list_newsfeed);
mImagePicker = view.findViewById(R.id.picker_image);
mPhotoView = view.findViewById(R.id.post_image);
AccountUtils.listenForUpdates(getActivity());
setClickListener(view);
setFocusListener(view);
return view;
}
@Override
public void onResume() {
super.onResume();
mPosts = PostUtils.loadNewsfeed(getActivity());
Account account = AccountUtils.loadAccount(getActivity());
mNewsfeedAdapter = new NewsfeedAdapter(getActivity(), mPosts, account);
mNewsfeed.setAdapter(mNewsfeedAdapter);
}
这是我的Profile片段中的生命周期方法,其中相同的功能应适用于稍有不同的数据集:
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_profile, container, false);
try {
if(getActivity().getIntent() != null && getActivity().getIntent().getAction().equals(FamilyProfileFragment.ACTION_EDIT_PROFILE)) {
mEditingSelf = false;
mIsParent = true;
mProfile = (Profile) getActivity().getIntent().getSerializableExtra(FamilyProfileFragment.EXTRA_PROFILE);
String selectedName = mProfile.getFirstName();
String loadedName = AccountUtils.loadProfile(getActivity()).getFirstName();
if(selectedName.equals(loadedName)) {
mEditingSelf = true;
}
}
else {
mEditingSelf = true;
mProfile = AccountUtils.loadProfile(getActivity());
if(mProfile instanceof Parent) {
mIsParent = true;
}
else {
mIsParent = false;
}
}
}
catch (Exception e) {
e.printStackTrace();
mEditingSelf = true;
mProfile = AccountUtils.loadProfile(getActivity());
if(mProfile instanceof Parent) {
mIsParent = true;
}
else {
mIsParent = false;
}
}
mAccount = AccountUtils.loadAccount(getActivity());
AccountUtils.loadProfilePhoto(getActivity(), view, mProfile.getProfileId());
mPhotoView = view.findViewById(R.id.profile_photo);
PostUtils.listenForTimeline(getActivity(), mProfile);
mPosts = PostUtils.loadTimeline(getActivity());
mTimeline = view.findViewById(R.id.list_posts);
setClickListener(view);
setTextDisplay(view);
populateProfile(view);
return view;
}
@Override
public void onResume() {
super.onResume();
mPosts = PostUtils.loadTimeline(getActivity());
mNewsfeedAdapter = new NewsfeedAdapter(getActivity(), mPosts, mAccount);
mTimeline.setAdapter(mNewsfeedAdapter);
}
答案 0 :(得分:0)
我的约束在Profile片段中设置不正确。将XML更新为以下内容:
<ListView
android:id="@+id/list_newsfeed"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/constraintLayout4" />