2016-05-03 1 views
0

Я создаю приложение, которое создает ImageButton каждый раз, когда пользователь выполняет определенное действие. Так что моя кнопка создается в динамическом режиме.Исключение нулевого указателя для разметки LayoutInflater и контейнера ViewGroup

У меня есть метод (createButton) внутри класса FRAGMENT, который получает изображение (которое используется в качестве фона моего ImageButton).

Моя проблема заключается в том, что мне, похоже, нужно использовать «LayoutInflater inflate» и «ViewGroup container», чтобы открыть мой относительный макет и добавить к нему динамическую кнопку, но я также передаю изображение этим методом, поэтому мой метод заставляет меня инициализировать раздувание и контейнер.

Я не могу инициализировать их до нуля, потому что тогда я получаю исключение NullPointerException при запуске моего приложения. Я также пытаюсь передать их из onCreateView (например, мой код ниже), но я все еще получаю исключение NullPointerException. Как использовать LayoutInflater inflate и контейнер ViewGroup (без инициализации их до нуля), в то же время передавая другим переменным мой метод. Я получаю исключение, прежде чем «tag-name: rLayout» будет напечатано.

public class HomeFragment extends Fragment { 

ViewGroup rootContainer; 
LayoutInflater rootInflater; 




@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; 
} 



// Create button from icon and image name 

public void createButton (BitmapDrawable bitmapdrawable, String applicationName){ 

    Log.d("tag_name", "createButton"); 

    //LayoutInflater inflater = (LayoutInflater)getContext().getSystemService 
      //(Context.LAYOUT_INFLATER_SERVICE); 

    try { 


     Log.d("tag_name", "Try_2"); 

     // Get Layout home_fragment 
     View rootView = rootInflater.inflate(R.layout.home_fragment, rootContainer, false); 
     RelativeLayout rLayout = (RelativeLayout) rootView.findViewById(R.id.home_fragment); 
     Log.d("tag_name", "rLayout"); 

     // create image button with background as bitmapdrawable 
     ImageButton btn = new ImageButton(getActivity()); 
     btn.setImageDrawable(bitmapdrawable); 
     int id = 1; 
     btn.setId(id); 
     Log.d("tag_name", "set the ID of the btn"); 

     // create textview with applicationName 
     //TextView appName = new TextView(getActivity()); 
     //appName.setText(applicationName); 

     // place new button next to existing button 
     RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
       RelativeLayout.LayoutParams.WRAP_CONTENT, 
       RelativeLayout.LayoutParams.WRAP_CONTENT); 


     params.addRule(RelativeLayout.RIGHT_OF, id); 
     btn.setLayoutParams(params); 

     // place text under newly created button 


     // Put button and text in layout 
     rLayout.addView(btn); 
     //rLayout.addView(appName); 
    } 

    catch (Exception e){ 

     System.out.println("Exception is "+e.toString()); 
    } 

} 

} 

Вот мой трассировки стека:

05-03 14:33:42.468 7197-7223/it.anddev.bradipao.janus D/tag_name: createButton 
05-03 14:33:42.468 7197-7223/it.anddev.bradipao.janus D/tag_name: Try_2 
05-03 14:33:42.468 7197-7223/it.anddev.bradipao.janus I/System.out: Exception is java.lang.NullPointerException 
05-03 14:33:42.468 7197-7223/it.anddev.bradipao.janus W/System.err: java.lang.NullPointerException 
05-03 14:33:42.468 7197-7223/it.anddev.bradipao.janus W/System.err:  at it.anddev.bradipao.janus.HomeFragment.createButton(HomeFragment.java:118) 
05-03 14:33:42.468 7197-7223/it.anddev.bradipao.janus W/System.err:  at it.anddev.bradipao.janus.MainActivity$1.run(MainActivity.java:155) 

Линия 118 в HomeFragment эта линия:

View rootView = rootInflater.inflate(R.layout.home_fragment, rootContainer, false); 

Линия 155 в моем mainActivity это вторая линия здесь, где я прохожу мои переменные в HomeFragment:

HomeFragment createbutton = new HomeFragment(); 
createbutton.createButton(bitmapdrawable, applicationName); 
+0

Я не понимаю, зачем нужно проходить инфлятор и контейнер? Ваш метод принимает BitmapDrawable, другие две переменные не нужно передавать, вы уже объявляете инфлятор внутри вашего createButton. Contdainer также не нужен, вы можете использовать null. – varunkr

+0

@varunkr, когда я делаю контейнер null (как и в моем коде), я получаю исключение, вызванное «NullPointerException». – Natalie

+0

Я не думаю, что нулевой указатель должен быть выброшен, хотя передача null в контейнере не всегда хорошая вещь. Поскольку все это происходит внутри фрагмента, вы можете попробовать передать корень фрагмента в качестве контейнера. Должно сработать !! – varunkr

ответ

1

Проблема заключается в том, как вы создать фрагмент и вызвать метод CreateButton над ним

HomeFragment createbutton = new HomeFragment(); 
createbutton.createButton(bitmapdrawable, applicationName); 

Вы не можете это сделать. Все действия, фрагменты и службы в Android должны проходить через их соответствующий жизненный цикл, чтобы у них был действительный контекст, связанный с ними.

Рассматривая их как обычный Java-класс, вы получаете нулевой контекст. Поскольку большинство методов в Деятельности, фрагменты или служба вызываются в его Контексте, вы получите исключение с нулевым указателем, поэтому ваше приложение аварийно завершает работу.

Что вам нужно!

FragmentTransaction fragmentTransaction = getSupportFragmentManager() 
     .beginTransaction(); 
Fragment profileFragment = new HomeFragment();//the fragment you want to show 
fragmentTransaction 
     .add(R.id.parent, profileFragment);//R.id.content_frame is the layout you want to replace 
fragmentTransaction.commit(); 

Вот как вы создаете свой фрагмент.

И для калибровки метода createButton вам нужен интерфейс.

Вам нужно будет создать интерфейс, как это в вас Fragment

public interface ButtonCreator{ 
    void buttonCreator(BitmapDrawable bitmapDrawable, String string); 
} 

И в вашей деятельности вам необходимо будет реализовать этот метод.Как это:

@Override 
public void buttonCreator(BitmapDrawable bitmap,String a) { 
    HomeFragment homeFragment = (HomeFragment)getSupportFragmentManager().getFragments().get(1); 
    homeFragment.createButton(bitmap,a); 
} 

Не забудьте реализовать интерфейс, как этот

public class MainActivity extends FragmentActivity implements MenuFragment.OnMenufragListener, HomeFragment.ButtonCreator { 

Также в вашем фрагменте вы должны получить это в методе onAttach

private ButtonCreator bc; 

@Override 
public void onAttach(Activity activity) { 
    super.onAttach(activity); 
    bc = (ButtonCreator) activity; 
} 

И вас будет звонить по телефону

buttonCreator(bitmapdrawable, applicationName); 

instaed от

createbutton.createButton(bitmapdrawable, applicationName); 

Это будет работать. Однако я также вижу ошибку в реализации вашей кнопки.

Вам нужно будет изучить его.

btn.setId(id); 

Выше линии необходим идентификатор типа R.id.something, а не целое число. Я уверен, что вы это решите.

+0

Я действительно надеялся, что это сработает, потому что я видел, как это работает для других, когда я просматриваю интернет, но я все еще получаю исключение NullPointerException. Я обновил свой вопрос, чтобы показать весь мой код. – Natalie

+0

Можете ли вы также опубликовать свою трассировку стека, что было бы полезно, странно, как теперь можно выбросить нулевой указатель! – varunkr

+0

@Natalie да ??? – varunkr

Смежные вопросы