我在片段中创建动态按钮时遇到问题。我的xml被称为“home_fragment”,这个布局似乎无法在“rootView”中找到,因为我在这一行抛出了NullPointerException:
RelativeLayout ll = (RelativeLayout)rootView.findViewById(R.id.home_fragment);
我的print语句确认“ll”变量为空。这是否与我使用片段的事实有关,因为这个用于创建动态按钮的代码似乎对其他人有效。 以下是我的代码 :
public class HomeFragment extends Fragment {
ViewGroup rootContainer;
LayoutInflater rootInflater;
private ButtonCreator bc;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
// onCreateView
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.home_fragment, container, false);
rootContainer = container;
rootInflater = inflater;
return view;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
bc = (ButtonCreator) activity;
}
public interface ButtonCreator{
void buttonCreator(Drawable drawable, String string);
}
// Create button from icon and image name
// Change Drawable back to BitmapDrawable
public void createButton (Drawable drawable, String applicationName){
Log.d("tag_name", "createButton");
try {
ImageButton btn = new ImageButton(getActivity());
btn.setImageDrawable(drawable);
View rootView = rootInflater.inflate(R.layout.home_fragment, rootContainer, false);
Log.d("tag_name", "RootInflater" +rootInflater);
Log.d("tag_name", "RootContainer" +rootContainer);
Log.d("tag_name", "RootView" +rootView);
RelativeLayout ll = (RelativeLayout)rootView.findViewById(R.id.home_fragment);
Log.d("tag_name", "RelativeLayout" +ll);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
ll.addView(btn, lp);
}
catch (Exception e){
System.out.println("Exception is "+e.toString());
e.printStackTrace();
}
}
}
这是home_fragment xml:
<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/home_fragment_scroll">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:layout_margin="5dp"
android:id="@+id/home_fragment"
>
</RelativeLayout>
</HorizontalScrollView>
以下是MainActivity:
public class MainActivity extends FragmentActivity implements MenuFragment.OnMenufragListener, HomeFragment.ButtonCreator {
// called when the activity is first created
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
RepeatTask();
}
@Override
public void onMenufrag(Fragment s) {
// get body fragment (native method is getFragmentManager)
HomeFragment fragment = (HomeFragment) getSupportFragmentManager().findFragmentById(R.id.home_fragment);
// if fragment is not null and in layout, set text, else launch BodyActivity
if ((fragment!=null)&&fragment.isInLayout()) {
fragment.getView();
} else {
Intent intent = new Intent(this,HomeFragment.class);
startActivity(intent);
}
}
@Override
public void buttonCreator(Drawable d,String a) {
HomeFragment homeFragment = (HomeFragment)getSupportFragmentManager().getFragments().get(1);
homeFragment.createButton(d,a);
}
private void RepeatTask()
{
repeatTaskThread = new Thread()
{
public void run()
{
while (true)
{
try {
String applicationName = "app";
Drawable draw = getResources().getDrawable(R.drawable.settings_camera);
buttonCreator(draw, applicationName);
//createbutton.createButton(bitmapdrawable, applicationName);
Log.d("tag_name", "Entered Home Fragment");
//socket.close();
} catch (Exception e) {
System.out.println("Exception is "+e.toString());
}
try
{
// Sleep for 5 seconds
Thread.sleep(5000);
}
catch (Exception e)
{
e.printStackTrace();
}
}
};
};
repeatTaskThread.start();
}
}
这是main.xml(片段的排列方式):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_gravity="center"
android:orientation="horizontal"
android:weightSum="1">
<fragment
android:id="@+id/menuFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
class="it.anddev.bradipao.janus.MenuFragment"
tools:layout="@layout/fr_menu">
</fragment>
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toEndOf="@id/menuFragment"
android:layout_toRightOf="@id/menuFragment"
android:layout_below="@+id/my_apps_container"
android:layout_alignBottom="@id/menuFragment" />
</RelativeLayout>
这是MenuFragment.java(对于fr_menu.xml,假设它只是一个空白的相对布局):
public class MenuFragment extends Fragment {
// activity listener
private OnMenufragListener menufragListener;
// interface for communication with activity
public interface OnMenufragListener {
public void onMenufrag(Fragment s);
}
// onAttach
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
menufragListener = (OnMenufragListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnMenufragListener");
}
}
// onCreate
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Create App with Body Fragment in display, and be able to replace it with other fragments
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.container, new HomeFragment()).commit();
}
// onActivityCreated
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
// onCreateView
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fr_menu, container, false);
return view;
}
// (recommended) method to send command to activity
private void sendBodyTextToActivity(Fragment s) {
menufragListener.onMenufrag(s);
}
}
这是我的StackTrace
05-04 19:05:40.452 3302-3325/it.anddev.bradipao.janus D/tag_name: createButton
05-04 19:05:40.452 3302-3325/it.anddev.bradipao.janus D/tag_name: RootInflatercom.android.internal.policy.impl.PhoneLayoutInflater@2204b848
05-04 19:05:40.452 3302-3325/it.anddev.bradipao.janus D/tag_name: RootContainerandroid.widget.FrameLayout{22047268 V.E..... ........ 254,67-772,583 #7f0b006b app:id/container}
05-04 19:05:40.452 3302-3325/it.anddev.bradipao.janus D/tag_name: RelativeLayoutnull
05-04 19:05:40.452 3302-3325/it.anddev.bradipao.janus I/System.out: Exception is java.lang.NullPointerException
05-04 19:05:40.452 3302-3325/it.anddev.bradipao.janus W/System.err: java.lang.NullPointerException
05-04 19:05:40.452 3302-3325/it.anddev.bradipao.janus W/System.err: at it.anddev.bradipao.janus.HomeFragment.createButton(HomeFragment.java:146)
05-04 19:05:40.462 3302-3325/it.anddev.bradipao.janus W/System.err: at it.anddev.bradipao.janus.MainActivity.buttonCreator(MainActivity.java:80)
05-04 19:05:40.462 3302-3325/it.anddev.bradipao.janus W/System.err: at it.anddev.bradipao.janus.MainActivity$1.run(MainActivity.java:166)
答案 0 :(得分:0)
所以,首先,这不是你加载片段的方式......它不是一个Activity,所以你不能用片段来启动活动。您需要像FragmentTransaction
内部一样使用MenuFragment.onCreate()
,但这应该看起来应该是您的活动onCreate()
。
Intent intent = new Intent(this,HomeFragment.class);
startActivity(intent);
反正,
你知道这一行正在返回null
RelativeLayout ll = (RelativeLayout)rootView.findViewById(R.id.home_fragment);
这是由于您重新膨胀片段XML布局造成的,这也可以通过替换此行来完成
View rootView = rootInflater.inflate(R.layout.home_fragment, rootContainer, false);
有了这个
View rootView = getView();
至于获取RelativeLayout,你可以在onCreateView
中完成private RelativeLayout ll;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.home_fragment, container, false);
ll = (RelativeLayout) view.findViewById(R.id.home_fragment);
return view;
}
public void createButton (Drawable drawable, String applicationName){
// Some code...
ll.addView();
}