片段 TextView 无法从 parcelable 对象更新
Posted
技术标签:
【中文标题】片段 TextView 无法从 parcelable 对象更新【英文标题】:Fragment TextView is not able to be updated from parcelable object 【发布时间】:2019-09-01 10:09:08 【问题描述】:在我的片段中,我有一个 textView,我想将其设置为特定的字符串。我想从一个对象中获取 textView 的字符串,我将其作为 parcelable 发送到片段。 我可以检索 parcelable 对象并使用该对象来获取字符串(当我记录它时,会显示正确的字符串)。但是当我想用它来设置textView时,textView并没有改变。
任何想法为什么会发生这种情况以及我该如何解决?
谢谢!
Edit1:我添加了片段所在的活动,也许错误在这里?
Edit2:我添加了 Data 类(parcelable 对象)。但是为了便于阅读,去掉了构造函数的内容。
public class NavigationFragment extends Fragment
private static final String TAG = "NavigationFragment";
public NavigationFragment()
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
View view = inflater.inflate(R.layout.fragment_navigation, container, false);
return view;
@Override
public void onViewCreated(@NonNull final View view, @Nullable Bundle savedInstanceState)
super.onViewCreated(view, savedInstanceState);
Bundle bundle = this.getArguments();
if(bundle!=null)
Data data = (Data) bundle.getParcelable("data");
TextView stopTitle = (TextView) view.findViewById(R.id.stopTitle);
final String name = data.getTourName();
Log.d(TAG, name);
stopTitle.setText(name);
<?xml version="1.0" encoding="utf-8"?>
<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_
android:layout_
android:background="@color/colorAccent"
tools:context=".DoTourActivity">
<TextView
android:id="@+id/stopTitle"
android:layout_
android:layout_
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
android:text="stopTitle"
android:textSize="30dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/imageView"
android:layout_
android:layout_
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.492"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/stopTitle"
tools:src="@drawable/placeholder_pic" />
<TextView
android:id="@+id/stopDescription"
android:layout_
android:layout_
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
android:text="stopDescriptionstopDescriptionstopDescription stopDescription stopDescription stopDescription stopDescription stopDescription stopDescription stopDescription stopDescriptionstopDescriptionstopDescription stopDescription stopDescription stopDescription stopDescription stopDescription stopDescription stopDescription"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView" />
<LinearLayout
android:id="@+id/linearLayout"
android:layout_
android:layout_
android:layout_marginStart="8dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="8dp"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/stopDescription">
<ImageView
android:id="@+id/imageView3"
android:layout_
android:layout_
android:layout_weight="1"
android:src="@android:drawable/ic_menu_mylocation" />
<TextView
android:id="@+id/locationAdress"
android:layout_
android:layout_
android:layout_weight="1"
android:text="locationAdress"
android:textSize="23dp" />
<ImageView
android:id="@+id/imageView2"
android:layout_
android:layout_
android:layout_weight="1"
android:src="@android:drawable/ic_dialog_map" />
</LinearLayout>
<EditText
android:id="@+id/pincode"
android:layout_
android:layout_
android:layout_marginStart="8dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="8dp"
android:ems="10"
android:inputType="number"
android:text="pincode"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linearLayout" />
<Button
android:id="@+id/confirmButton"
android:layout_
android:layout_
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="confirm"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/pincode" />
</android.support.constraint.ConstraintLayout>
public class DoTourActivity extends AppCompatActivity
private static final String TAG = "DoTourActivity";
private SectionStatePagerAdapter sectionStatePagerAdapter;
private ViewPager viewPager;
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_do_tour);
//Fragment management
sectionStatePagerAdapter = new SectionStatePagerAdapter(getSupportFragmentManager());
viewPager = (ViewPager) findViewById(R.id.container);
setupViewPager(viewPager);
//Setup actionbar
Toolbar myToolbar = (Toolbar) findViewById(R.id.app_bar);
setSupportActionBar(myToolbar);
//get chosen location & build tour
Fragment fragment = new NavigationFragment();
String location = getIntent().getStringExtra("location");
Bundle bundle = new Bundle();
Data data = new Data(location);
bundle.putParcelable("data", data);
fragment.setArguments(bundle);
//launch fragment
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.container, fragment);
transaction.commit();
public void setupViewPager (ViewPager viewPager)
SectionStatePagerAdapter adapter = new SectionStatePagerAdapter(getSupportFragmentManager());
adapter.addFragment(new NavigationFragment(), "navFragment");
adapter.addFragment(new QuestionFragment(), "qesFragment");
viewPager.setAdapter(adapter);
@Override
public boolean onCreateOptionsMenu(Menu menu)
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu);
@Override
public boolean onOptionsItemSelected(MenuItem item)
// switch(item.getItemId())
return super.onOptionsItemSelected(item);
public class Data implements Parcelable
public static final Parcelable.Creator CREATOR = new Parcelable.Creator()
public Data createFromParcel(Parcel in)
return new Data(in);
public Data[] newArray(int size)
return new Data[size];
;
private String tourName;
int tourID;
int possiblePoints;
int stops;
Spot[] spots;
//while playing tour
int points = 0;
// Constructor
public Data(String tour)
public String getTourName()
return tourName;
public void setTourName(String tourName)
this.tourName = tourName;
public int getTourID()
return tourID;
public void setTourID(int tourID)
this.tourID = tourID;
public int getPossiblePoints()
return possiblePoints;
public void setPossiblePoints(int possiblePoints)
this.possiblePoints = possiblePoints;
public int getStops()
return stops;
public void setStops(int stops)
this.stops = stops;
public Spot[] getSpots()
return spots;
public void setSpots(Spot[] spots)
this.spots = spots;
public int getPoints()
return points;
public void setPoints(int points)
this.points = points;
// Parcelling part
public Data(Parcel in)
this.tourName = in.readString();
this.tourID = in.readInt();
this.possiblePoints = in.readInt();
this.stops = in.readInt();
this.spots = in.createTypedArray(Spot.CREATOR);
this.points = in.readInt();
@Override
public int describeContents()
return 0;
@Override
public void writeToParcel(Parcel dest, int flags)
dest.writeString(this.tourName);
dest.writeInt(this.tourID);
dest.writeInt(this.possiblePoints);
dest.writeInt(this.stops);
for(Spot s : spots)
dest.writeParcelable(s, flags);
dest.writeInt(this.points);
【问题讨论】:
android:text="stopTitle" 显示了吗? 是的,它保持这样......不会更改为我想要设置的实际字符串。也许问题出在显示片段的活动上?我也会添加活动的代码。 尝试添加 stopTitle.setText("");就在这一行之后 stopTitle.setText(name);看看它是否真的连接了。 好吧,如果我把 stopTitle.setText("");在关闭 if 语句之后(然后在 if 语句之前移动 TextView stopTitle = (TextView) view.findViewById(R.id.stopTitle); 之后),文本设置为空。所以 stopTitle 元素实际上是连接的。一定是从 parcelable 或 bundle 中获取数据? @NikoK 也许你的Parcelable
实现不正确。您可以编辑您的问题以添加您的 Data
类及其与包裹相关的方法的源代码吗?
【参考方案1】:
感谢@Mike M。这已解决。
问题在于托管片段的活动。在那里,我创建了两个不同的 NavigationFragments,并将它们添加到活动中。 TextView 的更新发生在错误的地方。
【讨论】:
【参考方案2】:我从另一个答案中看到片段实例存在问题,但我相信您的 Parcelable
实现也存在问题。
public Data(Parcel in) ... this.spots = in.createTypedArray(Spot.CREATOR); ... @Override public void writeToParcel(Parcel dest, int flags) ... for(Spot s : spots) dest.writeParcelable(s, flags); ...
这两个调用需要镜像,目前不需要。与其自己遍历数组,不如使用writeTypedArray()
方法:
public Data(Parcel in)
...
this.spots = in.createTypedArray(Spot.CREATOR);
...
@Override
public void writeToParcel(Parcel dest, int flags)
...
dest.writeTypedArray(spots, flags);
...
如果您查看writeTypedArray()
和createTypedArray()
的实现,您会发现部分工作是编写一个指示数组大小的标志,以便代码知道要读取多少个实例在另一边出来。你的实现不包含这一步,所以两者会不兼容。
【讨论】:
以上是关于片段 TextView 无法从 parcelable 对象更新的主要内容,如果未能解决你的问题,请参考以下文章
无法从存储过程显示文本到 textview - Android SQL Server