我的目标:
大家好,我会尽力详细解释一切。
我有两个片段和一个主要活动。我想要实现的是,让用户从评级栏中选择评级。将该评级保存到变量中,并在第二个片段中显示该值。
我尝试使用Intent
和Bundle
实现此目的但是在启动时它会崩溃我的应用。在应用程序中,我有一个滑动tabLayout
,它有两个标签。标签1链接到OneFargment.java
,标签2链接到TwoFragment.java
我觉得这里使用接口的方法不起作用,因为每个片段都有不同的布局。任何帮助或指导将不胜感激。如果你们需要我发布XML文件的代码,请告诉我。
I am confused as how to recieve the values in my main activity, it seems that I need to define an ID to a fragment, but I dont have an id for fragment as each fragment has its own seperate layout file.
以下是我所有文件的代码。
OneFragment.java
package tanav.sharma;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RatingBar;
import android.widget.TextView;
import android.widget.Toast;
public class OneFragment extends Fragment {
OnFragmentSendVal vSendVal;
private RatingBar ratingBar;
private TextView txtRatingValue;
public interface OnFragmentSendVal{
public void onSentVal(float value);
}
public OneFragment() {
// Required empty public constructor
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try{
vSendVal = (OnFragmentSendVal)activity;
}catch (ClassCastException e){
throw new ClassCastException(activity.toString() + " must implement OnFragmentSendVal");
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.tanav_image,
container, false);
addListenerOnRatingBar(view);
return view;
}
public void addListenerOnRatingBar(View v) {
ratingBar = (RatingBar) v.findViewById(R.id.ratingBar);
txtRatingValue = (TextView) v.findViewById(R.id.value);
//if rating value is changed,
//display the current rating value in the result (textview) automatically
ratingBar.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
public void onRatingChanged(RatingBar ratingBar, float rating,
boolean fromUser) {
float val = rating;
vSendVal.onSentVal(val);
//txtRatingValue.setText(String.valueOf(rating));
}
});
}
}
TanavActivity.java
package tanav.sharma;
import android.content.Intent;
import android.support.v4.app.Fragment;
import android.content.DialogInterface;
import android.support.design.widget.TabLayout;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import java.util.ArrayList;
import java.util.List;
import android.view.View;
import android.widget.Button;
import android.widget.RatingBar;
import android.widget.TextView;
public class TanavActivity extends AppCompatActivity implements OneFragment.OnFragmentSendVal {
RatingBar rb;
TextView result;
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
private int[] tabIcons = {
R.drawable.ic_action_pro,
R.drawable.ic_action_web
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tanav);
toolbar = (Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
/**
* This button is responsible for taking the user back
* to the main activity. Preventing the user from pressing
* the back key multiple times.
*/
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
viewPager = (ViewPager)findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout)findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
setupTabIcons();
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
int count_image = 0;
int count_web = 0;
@Override
public void onTabSelected(TabLayout.Tab tab) {
int position = tab.getPosition();
if(position == 0){
count_image = count_image + 1;
TextView counter = (TextView) findViewById(R.id.counter);
counter.setText(Integer.toString(count_image));
}else if(position == 1){
//count_web = count_web + 1;
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
count_image = count_image + 1;
TextView counter = (TextView) findViewById(R.id.counter);
counter.setText(Integer.toString(count_image));
}
});
}
private void setupTabIcons(){
tabLayout.getTabAt(0).setIcon(tabIcons[0]);
tabLayout.getTabAt(1).setIcon(tabIcons[1]);
}
private void setupViewPager(ViewPager viewPager){
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new OneFragment(), getApplicationContext().getString(R.string.tanav));
adapter.addFragment(new TwoFragment(), getApplicationContext().getString(R.string.sharma));
viewPager.setAdapter(adapter);
}
@Override
public void onSentVal(float value) {
}
class ViewPagerAdapter extends FragmentPagerAdapter{
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
/**
* This function is responsible for prompting the user with a dialog box,
* once the hit the back key on the app. Asking for confirmation if they,
* really want to exit the app. If user selects Yes, the app will quit.
* If the user selects cancel, the app will continue to run.
*/
@Override
public void onBackPressed() {
CharSequence exit = getApplicationContext().getString(R.string.exit);
CharSequence exit_message = getApplicationContext().getString(R.string.exit_message);
new AlertDialog.Builder(this)
.setTitle(exit)
.setMessage(exit_message)
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
TanavActivity.super.onBackPressed();
}
}).create().show();
}
}
TwoFragment.java
package tanav.sharma;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class TwoFragment extends Fragment {
TextView lblResult;
public TwoFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.sharma_web, container, false);
String starRatings = getArguments().getString("stars");
lblResult = (TextView)view.findViewById(R.id.lblResult);
lblResult.setText(starRatings);
return view;
}
}
logcat的:
11-20 12:12:16.128 19867-19867/tanav.sharma E/AndroidRuntime: FATAL EXCEPTION: main
Process: tanav.sharma, PID: 19867
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.os.Bundle.getString(java.lang.String)' on a null object reference
at tanav.sharma.TwoFragment.onCreateView(TwoFragment.java:31)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2080)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1108)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1290)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:801)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:1638)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:679)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:143)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1240)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1088)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1614)
at android.view.View.measure(View.java:20221)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6333)
at android.support.design.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:700)
at android.support.design.widget.HeaderScrollingViewBehavior.onMeasureChild(HeaderScrollingViewBehavior.java:90)
at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onMeasureChild(AppBarLayout.java:1364)
at android.support.design.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:765)
at android.view.View.measure(View.java:20221)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6333)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:135)
at android.view.View.measure(View.java:20221)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6333)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:747)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:629)
at android.view.View.measure(View.java:20221)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6333)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.view.View.measure(View.java:20221)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6333)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:747)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:629)
at android.view.View.measure(View.java:20221)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6333)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at com.android.internal.policy.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:3111)
at android.view.View.measure(View.java:20221)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2687)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1640)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1932)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1528)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7564)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
at android.view.Choreographer.doCallbacks(Choreographer.java:686)
at android.view.Choreographer.doFrame(Choreographer.java:622)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7331)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.i
答案 0 :(得分:2)
要将数据从OneFragment
传递到TwoFragment
,您必须使用interface
实现互动,并且您不希望立即这样做,所以只需点击Communicating with Other Fragments的此链接即可并想到
HeadlinesFragment as fragment one
ArticleFragment as fragment
两个onListItemClick是你的onRatingChanged
并使用适当的int
参数和方法替换float
值
答案 1 :(得分:1)
然而它在发布时崩溃我的应用程序。
如果您的应用程序崩溃,请始终发布logcat,它会告诉每个人完全错误发生的位置。
你可能有多个错误,但我从一开始就看到了一个逻辑错误。
您将值存储为float
:
float val = rating;
...
i.putExtra("star",val);
但您尝试使用.getStringExtra()
来检索它......
String vals = i.getStringExtra("star");
请记住val
是 float
而非 String
,请使用相应的getter:
而是getFloatExtra()
。
float val = i.getFloatExtra("star");
答案 2 :(得分:0)
除了这里的其他答案,为了更灵活的方式,尝试使用SharedPreferences或staic变量。使用这些变量,您可以存储变量并在需要时检索它们,而不必立即启动活动。