Ton*_*ong 224 android android-fragments android-3.0-honeycomb
我想将一个片段添加到以编程方式实现其布局的Activity.我查看了Fragment文档,但没有很多示例描述我需要的内容.这是我尝试编写的代码类型:
public class DebugExampleTwo extends Activity {
    private ExampleTwoFragment mFragment;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FrameLayout frame = new FrameLayout(this);
        if (savedInstanceState == null) {
            mFragment = new ExampleTwoFragment();
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            ft.add(frame.getId(), mFragment).commit();
        }
        setContentView(frame);
    }
}
...
public class ExampleTwoFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, 
                             ViewGroup container, 
                             Bundle savedInstanceState) {
        Button button = new Button(getActivity());
        button.setText("Hello There");
        return button;
    }
}
此代码编译但在开始时崩溃,可能是因为我FragmentTransaction.add()的错误.这样做的正确方法是什么?
Ton*_*ong 189
事实证明,该代码存在多个问题.片段不能以与活动相同的java文件的方式声明,而不能作为公共内部类声明.框架期望片段的构造函数(没有参数)是公共的和可见的.将片段作为内部类移动到Activity中,或者为片段创建新的java文件修复它.
第二个问题是,当您以这种方式添加片段时,必须传递对片段包含视图的引用,并且该视图必须具有自定义ID.使用默认ID会使应用程序崩溃.这是更新的代码:
public class DebugExampleTwo extends Activity {
    private static final int CONTENT_VIEW_ID = 10101010;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FrameLayout frame = new FrameLayout(this);
        frame.setId(CONTENT_VIEW_ID);
        setContentView(frame, new LayoutParams(
            LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        if (savedInstanceState == null) {
            Fragment newFragment = new DebugExampleTwoFragment();
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            ft.add(CONTENT_VIEW_ID, newFragment).commit();
        }
    }
    public static class DebugExampleTwoFragment extends Fragment {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            EditText v = new EditText(getActivity());
            v.setText("Hello Fragment!");
            return v;
        }
    }
}
JJD*_*JJD 63
这是我在阅读Tony Wong的评论后想出的:
public class DebugExampleTwo extends BaseActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addFragment(android.R.id.content,
                    new DebugExampleTwoFragment(),
                    DebugExampleTwoFragment.FRAGMENT_TAG);
    }
}
...
public abstract class BaseActivity extends Activity {
    protected void addFragment(@IdRes int containerViewId,
                               @NonNull Fragment fragment,
                               @NonNull String fragmentTag) {
        getSupportFragmentManager()
                .beginTransaction()
                .add(containerViewId, fragment, fragmentTag)
                .disallowAddToBackStack()
                .commit();
    }
    protected void replaceFragment(@IdRes int containerViewId,
                                   @NonNull Fragment fragment,
                                   @NonNull String fragmentTag,
                                   @Nullable String backStackStateName) {
        getSupportFragmentManager()
                .beginTransaction()
                .replace(containerViewId, fragment, fragmentTag)
                .addToBackStack(backStackStateName)
                .commit();
    }
}
...
public class DebugExampleTwoFragment extends Fragment {
    public static final String FRAGMENT_TAG = 
        BuildConfig.APPLICATION_ID + ".DEBUG_EXAMPLE_TWO_FRAGMENT_TAG";
    // ...
}
ana*_*ish 31
    public class Example1 extends FragmentActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
          DemoFragment fragmentDemo = (DemoFragment) 
          getSupportFragmentManager().findFragmentById(R.id.frame_container);
          //above part is to determine which fragment is in your frame_container
          setFragment(fragmentDemo);
                       (OR)
          setFragment(new TestFragment1());
        }
        // This could be moved into an abstract BaseActivity 
        // class for being re-used by several instances
        protected void setFragment(Fragment fragment) {
            FragmentManager fragmentManager = getSupportFragmentManager();
            FragmentTransaction fragmentTransaction = 
                fragmentManager.beginTransaction();
            fragmentTransaction.replace(android.R.id.content, fragment);
            fragmentTransaction.commit();
        }
    }
要将片段添加到Activity或FramentActivity中,它需要一个Container.该容器应该是一个"
Framelayout",可以包含在xml中,否则你可以使用默认容器android.R.id.content来删除或替换Activity中的片段.
main.xml中
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
 <!-- Framelayout to display Fragments -->
   <FrameLayout
        android:id="@+id/frame_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <ImageView
        android:id="@+id/imagenext"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_margin="16dp"
        android:src="@drawable/next" />
</RelativeLayout>
Xen*_*one 27
阅读完所有答案后,我想出了优雅的方式:
public class MyActivity extends ActionBarActivity {
 Fragment fragment ;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    FragmentManager fm = getSupportFragmentManager();
    fragment = fm.findFragmentByTag("myFragmentTag");
    if (fragment == null) {
        FragmentTransaction ft = fm.beginTransaction();
        fragment =new MyFragment();
        ft.add(android.R.id.content,fragment,"myFragmentTag");
        ft.commit();
    }
}
基本上你不需要添加frameLayout作为你的片段的容器,你可以直接将片段添加到android root视图容器中
重要提示:不要使用替换片段作为此处显示的大部分方法,除非您不介意在重新创建过程中丢失片段变量实例状态.
要在 Kotlin 中以编程方式将片段附加到活动,您可以查看以下代码:
主活动.kt
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
            // create fragment instance
            val fragment : FragmentName = FragmentName.newInstance()
            // for passing data to fragment
            val bundle = Bundle()
            bundle.putString("data_to_be_passed", DATA)
            fragment.arguments = bundle
            // check is important to prevent activity from attaching the fragment if already its attached
            if (savedInstanceState == null) {
                supportFragmentManager
                    .beginTransaction()
                    .add(R.id.fragment_container, fragment, "fragment_name")
                    .commit()
            }
        }
    }
}
活动_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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"
    tools:context=".ui.MainActivity">
    <FrameLayout
        android:id="@+id/fragment_container"
        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_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
片段名称.kt
class FragmentName : Fragment() {
    companion object {
        fun newInstance() = FragmentName()
    }
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        // receiving the data passed from activity here
        val data = arguments!!.getString("data_to_be_passed")
        return view
    }
    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
    }
}
对于API 级别 17或更高,View.generateViewId()将解决此问题。实用程序方法提供了一个在构建时不使用的唯一 id。
public abstract class SingleFragmentActivity extends Activity {
    public static final String FRAGMENT_TAG = "single";
    private Fragment fragment;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
        if (savedInstanceState == null) {
            fragment = onCreateFragment();
           getFragmentManager().beginTransaction()
                   .add(android.R.id.content, fragment, FRAGMENT_TAG)
                   .commit();
       } else {
           fragment = getFragmentManager().findFragmentByTag(FRAGMENT_TAG);
       }
   }
   public abstract Fragment onCreateFragment();
   public Fragment getFragment() {
       return fragment;
   }
}
使用
public class ViewCatalogItemActivity extends SingleFragmentActivity {
    @Override
    public Fragment onCreateFragment() {
        return new FragmentWorkShops();
    }
}
这可能对你有帮助
定义片段
为片段视图创建xml文件fragment_abc.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="TextView" />
<Button
    android:id="@+id/button1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Button" />
</LinearLayout>
创建片段ABCFragment.java
import androidx.fragment.app.Fragment;
public class FooFragment extends Fragment {
// The onCreateView method is called when Fragment should create its View object hierarchy,
// either dynamically or via XML layout inflation. 
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle 
savedInstanceState) {
    // Defines the xml file for the fragment
    return inflater.inflate(R.layout.fragment_abc, parent, false);
}
// This event is triggered soon after onCreateView().
// Any view setup should occur here.  E.g., view lookups and attaching view listeners.
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    // Setup any handles to view objects here
    // EditText etFoo = (EditText) view.findViewById(R.id.etFoo);
}
}
在您的活动中添加frameLayout
<FrameLayout
   android:id="@+id/your_placeholder"
   android:layout_width="match_parent"
   android:layout_height="match_parent">
现在在活动中,添加以下方法
protected void setFragment() {
    // Begin the transaction
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    // Replace the contents of the container with the new fragment
    ft.replace(R.id.fragment_container, new ABCFragment());
    // or ft.add(R.id.your_placeholder, new ABCFragment());
    // Complete the changes added above
    ft.commit();
}
参考:https://guides.codepath.com/android/creating-and-using-fragments#defining-a-fragment
| 归档时间: | 
 | 
| 查看次数: | 424969 次 | 
| 最近记录: |