Scrollview 问题中的自定义 xml 布局膨胀器
Custom xml layout inflater in Scrollview issue
我成功地将我的自定义 XML 布局扩展到我的代码中,它根据数组的项目数显示在应用程序中,尽管我只获得第一个项目的数据(头像图像及其用户名文本),从第二项开始,我得到默认布局的图像和文本,这是我的代码:
//-----------------------------------------------
// MARK - QUERY MOMENTS
//-----------------------------------------------
void queryMoments() {
Log.i(Configurations.TAG, "QUERY MOMENTS...");
ParseUser currentUser = ParseUser.getCurrentUser();
List<String>currUserObjID = new ArrayList<>();
currUserObjID.add(currentUser.getObjectId());
// Clear moments array
momentsArray = new ArrayList<>();
// Launch query
ParseQuery<ParseObject>query = ParseQuery.getQuery(Configurations.MOMENTS_CLASS_NAME);
query.whereContainedIn(Configurations.MOMENTS_FOLLOWED_BY, currUserObjID);
query.orderByDescending(Configurations.MOMENTS_CREATED_AT);
query.findInBackground(new FindCallback<ParseObject>() {
@Override
public void done(List<ParseObject> objects, ParseException e) {
if (e == null) {
// Some Moment exists
if (objects.size() != 0) {
momentsArray = objects;
// Scrollview and embedded Layout
final HorizontalScrollView sv = findViewById(R.id.hMomentsScrollView);
final LinearLayout momentsLayout = findViewById(R.id.hMomentsLayout);
momentsLayout.setOrientation(LinearLayout.HORIZONTAL);
momentsLayout.removeAllViews();
for (int i=0; i<momentsArray.size(); i++) {
final ParseObject mObj = objects.get(i);
// Get userPointer
mObj.getParseObject(Configurations.MOMENTS_USER_POINTER).fetchIfNeededInBackground(new GetCallback<ParseObject>() {
public void done(final ParseObject userPointer, ParseException e) {
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
momentsLayout.addView(inflater.inflate(R.layout.moment_layout, sv, false));
// ------------------------------------------------
// MARK: - WATCH MOMENT'S VIDEO BUTTON
// ------------------------------------------------
CircleImageView avImg = findViewById(R.id.mlAvatarImg);
Configurations.getParseImage(avImg, userPointer, Configurations.USER_AVATAR);
avImg.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(ctx, WatchVideo.class);
Bundle extras = new Bundle();
extras.putString("objectID", mObj.getObjectId());
i.putExtras(extras);
startActivity(i);
}});
// Username Txt
TextView uTxt = findViewById(R.id.mlUsernameTxt);
uTxt.setTypeface(Configurations.osItalic);
uTxt.setText(userPointer.getString(Configurations.USER_USERNAME));
}});// end userPointer
}// ./For loop
// error
} else { Configurations.simpleAlert(e.getMessage(),ctx); }
}}});// ./ query
这是我的 moment_layout.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:layout_width="match_parent"
android:layout_height="match_parent">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/mlAvatarImg"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="25dp"
android:src="@drawable/default_avatar"
app:civ_border_color="@color/main_color"
app:civ_border_width="2dp"/>
<TextView
android:id="@+id/mlUsernameTxt"
android:layout_width="50dp"
android:layout_height="20dp"
android:layout_alignParentStart="true"
android:layout_below="@+id/mlAvatarImg"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:gravity="center_vertical"
android:text="•••"
android:textAlignment="center"
android:textSize="10sp"
android:textStyle="italic"/>
</RelativeLayout>
我的 ScrollView XML 代码:
<HorizontalScrollView
android:id="@+id/hMomentsScrollView"
android:layout_width="280dp"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_marginStart="80dp">
<LinearLayout
android:id="@+id/hMomentsLayout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
</LinearLayout>
</HorizontalScrollView>
所以,让我们假设我的 momentsArray 有 2 个项目(我从 Logcat 中正确地得到它们),如果 johndoe,另一个是sarahdoe。我得到的是 johndoe 的图像和用户名,这是第一个数组的项目,然后我得到一个空的 ImageView 和 TextView 视图作为第二个项目,尽管我的 Logcat 显示 sarahdoe 作为第二项。
我尝试了更多项,结果相同,从第 2 项开始,它们都显示默认的 ImageView 和 textView。
我在上面的代码中做错了什么吗?这是我得到的屏幕截图:
根据您提供的信息,我可以假设您正在重新发明轮子。
要归档视图列表的水平滚动行为,您需要做的是在水平配置中使用 RecyclerView 并使用 RecyclerView Adapter用相应的信息将项目充气到其中。从哪里开始可以找到 here.
P.S。要将 RecyclerView 设置为水平滚动,您可以在 XML 中指定 "orientation" 属性,如下所示:
<android.support.v7.widget.RecyclerView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layoutManager="android.support.v7.widget.LinearLayoutManager" />
上面提到的方法不仅是正确的方法,而且在显示大量项目时也很高效。
希望这对您有所帮助。祝你好运:)
如上所述 - 不要重新发明轮子并使用 RecyclerView。
但在当前代码中,要点是您试图从根滚动视图中获取每个占位符但具有相同的 ID,这将始终是 return 第一个子
findViewById(R.id.mlUsernameTxt)
你应该这样做:
View placeholder = inflater.inflate(R.layout.moment_layout, momentsLayout, false);
momentsLayout.addView(placeholder)
TextView uTxt = placeholder.findViewById(R.id.mlUsernameTxt);
我成功地将我的自定义 XML 布局扩展到我的代码中,它根据数组的项目数显示在应用程序中,尽管我只获得第一个项目的数据(头像图像及其用户名文本),从第二项开始,我得到默认布局的图像和文本,这是我的代码:
//-----------------------------------------------
// MARK - QUERY MOMENTS
//-----------------------------------------------
void queryMoments() {
Log.i(Configurations.TAG, "QUERY MOMENTS...");
ParseUser currentUser = ParseUser.getCurrentUser();
List<String>currUserObjID = new ArrayList<>();
currUserObjID.add(currentUser.getObjectId());
// Clear moments array
momentsArray = new ArrayList<>();
// Launch query
ParseQuery<ParseObject>query = ParseQuery.getQuery(Configurations.MOMENTS_CLASS_NAME);
query.whereContainedIn(Configurations.MOMENTS_FOLLOWED_BY, currUserObjID);
query.orderByDescending(Configurations.MOMENTS_CREATED_AT);
query.findInBackground(new FindCallback<ParseObject>() {
@Override
public void done(List<ParseObject> objects, ParseException e) {
if (e == null) {
// Some Moment exists
if (objects.size() != 0) {
momentsArray = objects;
// Scrollview and embedded Layout
final HorizontalScrollView sv = findViewById(R.id.hMomentsScrollView);
final LinearLayout momentsLayout = findViewById(R.id.hMomentsLayout);
momentsLayout.setOrientation(LinearLayout.HORIZONTAL);
momentsLayout.removeAllViews();
for (int i=0; i<momentsArray.size(); i++) {
final ParseObject mObj = objects.get(i);
// Get userPointer
mObj.getParseObject(Configurations.MOMENTS_USER_POINTER).fetchIfNeededInBackground(new GetCallback<ParseObject>() {
public void done(final ParseObject userPointer, ParseException e) {
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
momentsLayout.addView(inflater.inflate(R.layout.moment_layout, sv, false));
// ------------------------------------------------
// MARK: - WATCH MOMENT'S VIDEO BUTTON
// ------------------------------------------------
CircleImageView avImg = findViewById(R.id.mlAvatarImg);
Configurations.getParseImage(avImg, userPointer, Configurations.USER_AVATAR);
avImg.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(ctx, WatchVideo.class);
Bundle extras = new Bundle();
extras.putString("objectID", mObj.getObjectId());
i.putExtras(extras);
startActivity(i);
}});
// Username Txt
TextView uTxt = findViewById(R.id.mlUsernameTxt);
uTxt.setTypeface(Configurations.osItalic);
uTxt.setText(userPointer.getString(Configurations.USER_USERNAME));
}});// end userPointer
}// ./For loop
// error
} else { Configurations.simpleAlert(e.getMessage(),ctx); }
}}});// ./ query
这是我的 moment_layout.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:layout_width="match_parent"
android:layout_height="match_parent">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/mlAvatarImg"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="25dp"
android:src="@drawable/default_avatar"
app:civ_border_color="@color/main_color"
app:civ_border_width="2dp"/>
<TextView
android:id="@+id/mlUsernameTxt"
android:layout_width="50dp"
android:layout_height="20dp"
android:layout_alignParentStart="true"
android:layout_below="@+id/mlAvatarImg"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:gravity="center_vertical"
android:text="•••"
android:textAlignment="center"
android:textSize="10sp"
android:textStyle="italic"/>
</RelativeLayout>
我的 ScrollView XML 代码:
<HorizontalScrollView
android:id="@+id/hMomentsScrollView"
android:layout_width="280dp"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_marginStart="80dp">
<LinearLayout
android:id="@+id/hMomentsLayout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
</LinearLayout>
</HorizontalScrollView>
所以,让我们假设我的 momentsArray 有 2 个项目(我从 Logcat 中正确地得到它们),如果 johndoe,另一个是sarahdoe。我得到的是 johndoe 的图像和用户名,这是第一个数组的项目,然后我得到一个空的 ImageView 和 TextView 视图作为第二个项目,尽管我的 Logcat 显示 sarahdoe 作为第二项。
我尝试了更多项,结果相同,从第 2 项开始,它们都显示默认的 ImageView 和 textView。
我在上面的代码中做错了什么吗?这是我得到的屏幕截图:
根据您提供的信息,我可以假设您正在重新发明轮子。
要归档视图列表的水平滚动行为,您需要做的是在水平配置中使用 RecyclerView 并使用 RecyclerView Adapter用相应的信息将项目充气到其中。从哪里开始可以找到 here.
P.S。要将 RecyclerView 设置为水平滚动,您可以在 XML 中指定 "orientation" 属性,如下所示:
<android.support.v7.widget.RecyclerView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layoutManager="android.support.v7.widget.LinearLayoutManager" />
上面提到的方法不仅是正确的方法,而且在显示大量项目时也很高效。
希望这对您有所帮助。祝你好运:)
如上所述 - 不要重新发明轮子并使用 RecyclerView。
但在当前代码中,要点是您试图从根滚动视图中获取每个占位符但具有相同的 ID,这将始终是 return 第一个子
findViewById(R.id.mlUsernameTxt)
你应该这样做:
View placeholder = inflater.inflate(R.layout.moment_layout, momentsLayout, false);
momentsLayout.addView(placeholder)
TextView uTxt = placeholder.findViewById(R.id.mlUsernameTxt);