I am a newbie in Android programming and I have this problem:
In this simple example, when I click on start button, I run a fragment. When I click on alarm button, I write in a log file.
Now, if I click first the start button, later the alarm button don't run. I think the problem is the fragment don't leave the interaction with user. Can you help me?
best regads
A.
public class MainActivity extends FragmentActivity {
private static final String FRAG1_TAG = MainActivity.class.getCanonicalName() +".fragment1";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button buttonStart = (Button) findViewById(R.id.buttonStart);
buttonStart.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Log.i("exemple", "start button Start !!!!!!");
goFragment();
}
});
Button buttonAllarm = (Button) findViewById(R.id.buttonAllarm);
buttonAllarm.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Log.i("exemple", "start button allarm !!!!!!");
}// fine onClick
});// fine onClickListner
}
void goFragment() {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction xact = fm.beginTransaction();
if (null == fm.findFragmentByTag(FRAG1_TAG)) {
xact.replace(android.R.id.content, new ListFramment(), FRAG1_TAG);
xact.addToBackStack (null); // questo serve devi metterlo
xact.commit();
}
}
this is the fragment
public class ListFramment extends ListFragment {
// onCreate
#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.activity_main, null);
AppLog.logString("Parte onCreateView");
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
AppLog.logString("Parte onActivityCreated");
ArrayList<Map<String, String>> list = buildData();
String[] from = { "name", "purpose" };
int[] to = { android.R.id.text1, android.R.id.text2 };
SimpleAdapter adapter = new SimpleAdapter(getActivity(), list,
android.R.layout.simple_list_item_2, from, to);
setListAdapter(adapter);
}
private ArrayList<Map<String, String>> buildData() {
ArrayList<Map<String, String>> list = new ArrayList<Map<String, String>>();
list.add(putData("Android", "Mobile"));
list.add(putData("iPhone", "iPhone"));
return list;
// TODO Auto-generated method stub
}
private HashMap<String, String> putData(String name, String purpose) {
HashMap<String, String> item = new HashMap<String, String>();
item.put("name", name);
item.put("purpose", purpose);
return item;
}
}
Your problem is here:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_main, null);
AppLog.logString("Parte onCreateView");
return view;
}
Your Fragment is inflating the same layout as the Activity that created it. But the Fragment does not have any onClickListeners. I suspect that the Fragment layout is covering up the Activity layout, duplicating it exactly, with non-functional buttons. That would explain why the button click works only the first time.
It would be normal for the Fragment to have its own layout, different from the Activity.
Not seeing your layout file does not help. But I suspect it got nothing to do with fragments.
Related
MainActivity on startup add a fragment layout to Relativeview, then i send a data to fragment to add it to ExpandablelistView but my app shows me error that couldn't recognize ExpandablelistView.
MainActivity:
public class MainActivity extends AppCompatActivity implements FragmentAddCatergory.onClickButtonListener {
private FragmentManager manager;
private FragmentTransaction transactionShowList;
private FragmentTransaction transactionAddCatergory;
private FragmentAddCatergory addCatergory;
private FragmentShowCategory showCategory;
private boolean addcategory;
private TextView txtAddCategory;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
manager = getFragmentManager();
transactionShowList = manager.beginTransaction();
showCategory = new FragmentShowCategory();
addCatergory=new FragmentAddCatergory();
transactionShowList.add(R.id.Fragment_container, showCategory);
transactionShowList.commit();
addcategory=false;
txtAddCategory = (TextView) findViewById(R.id.txtaddcategory);
txtAddCategory.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ChangeFragment();
}
});
}
public void ChangeFragment(){
transactionAddCatergory=manager.beginTransaction();
if (addcategory){
transactionAddCatergory.replace(R.id.Fragment_container,addCatergory);
txtAddCategory.setText("Do you want to see your List?Show me!");
addcategory=false;
}else{
transactionAddCatergory.replace(R.id.Fragment_container,showCategory);
txtAddCategory.setText("Do you want to add a Category?Create One");
addcategory=true;
}
transactionAddCatergory.commit();
}
#Override
public void ClickButton(String group, String child) {
FragmentShowCategory a=new FragmentShowCategory();
a.showExpand(this,group,child);
}}
in last above code i make object from first fragment and send a data and in below code is code of first fragment
public class FragmentShowCategory extends Fragment {
private View view;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
view = inflater.inflate(R.layout.activity_expandable_list_view, container, false);
return view;
}
public void showExpand(Context context, String g, String c) {
Toast.makeText(context, g + " is " + c, Toast.LENGTH_LONG).show();
HashMap<String, List<String>> carsDetails = DataProvider.getInfo(g, c);
List<String> carsBrands = new ArrayList<String>(carsDetails.keySet());
ItemClass adapter = new ItemClass(context, carsDetails, carsBrands);
ExpandableListView list = (ExpandableListView) view.findViewById(R.id.expandList);
list.setAdapter(adapter);
}}
but when i ran my app, i get error that i don't know why in line of:
ExpandableListView list = (ExpandableListView) view.findViewById(R.id.expandList);
i'd appreciate to help me.
Your fragment's view hierarchy is not inflated automatically just because you created an instance of your fragment, as you do in ClickButton. The onCreateView() method that has to be called first in order to inflate your views is part of the fragment's lifecycle. You should let Android instantiate your fragment, and acquire it's instance through the FragmentManager.
This tutorial explains basics about fragments very well.
I am using nav drawer. So i need from Fragment start Activity in which i start another Activity where i have ListView,clicking on which i must save data.
After save i need to return to Fragment where saved Data must be showing.
So here is my Fragment
public class ArmoryFragment extends Fragment {
public ArmoryFragment(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_armory, container, false);
Button button = (Button) rootView.findViewById(R.id.button_rifles);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), Rifles.class);
startActivity(intent);
}
});
return rootView;
}
}
and here is my activivty from where i need to return
public class Rifles extends Activity implements View.OnClickListener, OnItemSelectedListener {
DatabaseHelper db;
String BrandModel;
private RifleDAO rifleDAO;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.rifles);
initList();
this.rifleDAO = new RifleDAO(this);
ListView listView = (ListView) findViewById(R.id.listView1);
SimpleAdapter simpleAdapter = new SimpleAdapter(this, riflesList, android.R.layout.simple_list_item_1, new String[] {"rifle"}, new int[] {android.R.id.text1});
listView.setAdapter(simpleAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
String item = ((TextView)view).getText().toString();
Toast.makeText(getBaseContext(), item, Toast.LENGTH_LONG).show();
BrandModel= ((TextView)view).getText().toString();
String[] parts=BrandModel.split(" ");
String Brand=parts[0];
String Model = parts[1];
// need to return from somewhere here
}
});
} next is parser code... supose it is not needed
So how can I return from Activity to Fragment?
Well if you want to save data, I prefer adding the data to a table in your database (obviously you have a databaseHelper class so make you own table) and when you are back from your activity put extra a position you want and call :
selectItem(mCurrentSelectedPosition);
so mCurrentSelectedPosition is the position of the fragment that you want to be selected.
I'm making a simple app where I'll have two level lists. I've created the first level list with ListView but I'm not sure how to go about creating second level list.
Example:
First level list is:
Fruits
Cookies
When Fruits is clicked then the list below is shown:
Bananans
Grapes
Apples
When cookies is clicked then the list below is shown:
Oreo's
Choc Chip
Code for first level list:
public class MainActivity extends SherlockActivity {
SimpleAdapter simpleAdpt;
List<Map<String, String>> list1 = new ArrayList<Map<String,String>>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initList();
ListView lv = (ListView) findViewById(R.id.listView);
simpleAdpt = new SimpleAdapter(this, list1, android.R.layout.simple_list_item_1, new String[] {"list1"}, new int[] {android.R.id.text1});
lv.setAdapter(simpleAdpt);
}
private void initList() {
// We populate the planets
list1.add(creatList1("list1", "Fruits"));
list1.add(creatList1("list1", "Cookies"));
}
private HashMap<String, String> creatList1(String key, String name) {
HashMap<String, String> list = new HashMap<String, String>();
list.put(key, name);
return list;
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
}
}
Check out for ExpandableListView. I suits to your need.
I have an app that shows a listView inside a fragment ok
now I need to animate the list view out
but the animation
animate()
is not working
here the code,
public class PhoneMainView extends SherlockFragment{
ListView listView ;
TranslateAnimation mAnimation;
//testeo
private Button btnNewEmpresa;
RelativeLayout lLayoutFrgValidate;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
Log.d("mensa", "ONCREATE");
lLayoutFrgValidate=(RelativeLayout) inflater.inflate(R.layout.activity_main, container, false);
btnNewEmpresa=(Button) lLayoutFrgValidate.findViewById(R.id.button_anima);
btnNewEmpresa.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
Log.d("mensa", "sikas");
animate();
}
});
return lLayoutFrgValidate;
}
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
Log.d("mensa", "onActivityCreated");
listView = (ListView) getView().findViewById(R.id.listViewCats);
String[] values = new String[] { "C0","C1","C2","C3", "C4", "C5", "C6","C7"
};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, values);
listView.setAdapter(adapter);
}
public void animate() {
mAnimation = new TranslateAnimation(0, 0, 0, 599);
mAnimation.setDuration(10000);
mAnimation.setFillAfter(true);
mAnimation.setRepeatCount(-1);
mAnimation.setRepeatMode(Animation.REVERSE);
listView.setAnimation(mAnimation);
}
}
You need to start the animation.
listView.startAnimation(mAnimation); // Use this
It's small Android 2.2 test application using the Compatibility Package. I am trying to update the textview on another fragment on another activity on list item selection. But problem is that everytime the first click returns nullpointer exception and only on the second try its text is changing. I would like to know why is the happening and what is a good solution.
ListActivity:-
public class ListActivity extends FragmentActivity implements
ListFragment.OnItemSelectedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
}
#Override
public void onItemSelected(int index) {
// TODO Auto-generated method stub
// Check to see if there is a frame in which to embed the
// detail fragment directly in the containing UI.
View detailsFrame = findViewById(R.id.detailcontainer);
if (detailsFrame != null
&& detailsFrame.getVisibility() == View.VISIBLE) {
DetailFragment detailFragment = (DetailFragment) getSupportFragmentManager()
.findFragmentById(R.id.detailcontainer);
if (detailFragment == null) {
detailFragment = new DetailFragment();
}
// Execute a transaction, replacing any existing fragment
// with this one inside the frame.
getSupportFragmentManager().beginTransaction()
.replace(R.id.detailcontainer, detailFragment).commit();
detailFragment.setTextView(index);
} else {
// Otherwise we need to launch a new activity to display
Intent intent = new Intent(this, DetailActivity.class);
intent.putExtra("index", index);
startActivity(intent);
}
}
}
ListFragment :-
public class ListFragment extends Fragment {
private OnItemSelectedListener listener;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String[] countries = new String[] { "India", "Pakistan", "Sri Lanka",
"China", "Bangladesh", "Nepal", "Afghanistan", "North Korea",
"South Korea", "Japan" };
View view = inflater.inflate(R.layout.list_fragment, container, false);
ListView listView = (ListView) view.findViewById(R.id.listView);
// Populate list
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
this.getActivity(), android.R.layout.simple_list_item_1,
countries);
listView.setAdapter(adapter);
// operation to do when an item is clicked
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(getActivity(), "ListItem Number " + position,
Toast.LENGTH_SHORT).show();
listener.onItemSelected(position);
}
});
return view;
}
// Container Activity must implement this interface
public interface OnItemSelectedListener {
public void onItemSelected(int index);
}
// To ensure that the host activity implements this interface
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof OnItemSelectedListener) {
listener = (OnItemSelectedListener) activity;
} else {
throw new ClassCastException(activity.toString()
+ " must implemenet ListFragment.OnItemSelectedListener");
}
}
public void operation(int index) {
listener.onItemSelected(index);
}
}
Detail Activity :-
public class DetailActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DetailFragment details;
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
finish();
return;
}
if (savedInstanceState == null) {
// During initial setup, plug in the details fragment.
details = new DetailFragment();
details.setArguments(getIntent().getExtras());
getSupportFragmentManager().beginTransaction()
.add(android.R.id.content, details).commit();
}
Bundle extras = getIntent().getExtras();
int index = extras.getInt("index");
try {
details = (DetailFragment) getSupportFragmentManager()
.findFragmentById(R.id.detailfragment);
details.setTextView(index);
} catch (NullPointerException ex) {
ex.getStackTrace();
}
}
}
DetailFragment :-
public class DetailFragment extends Fragment {
String[] capitals;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (container == null)
return null;
capitals = new String[] { "delhi", "karachi", "colombo", "beijing",
"dhaka", "katmandu", "Afghanistan", "pyongyang", "seoul",
"tokyo" };
View v = inflater.inflate(R.layout.detail_fragment, container, false);
return v;
}
public void setTextView(int index) {
try {
TextView view = (TextView) getView().findViewById(R.id.detailView);
view.setText(capitals[index]);
} catch (NullPointerException ex) {
ex.getStackTrace();
}
}
public int getShownIndex() {
return getArguments().getInt("index", 0);
}
}
Update:- I am adding the detailFragment xml:-
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:background="#color/lightblue"
android:orientation="vertical" >
<TextView
android:id="#+id/detailView"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="#string/detail_frag" />
</RelativeLayout>
Instead of doing details.setTextView(index) in DetailActivity , set the value of TextView in the DetailFragment's onActivityCreated while passing the value to be set in fragments setArgument method in the Detailactivity...
DetailsFragment details = new DetailsFragment();
details.setArguments(getIntent().getExtras()); // pass the value of text view here
And In fragment onActivityCreated get that value via getArguments() and set it in textview..
EDIT for sending value Selected to loaded Fragment
In List Activity
detailFragment = getFragmentbyTag
if(detailFragment == null)
Create Fragment and Add it and Set Arguments here as well
else
detailFragment.setTextView(value); // fragment already loaded no need to set arguments
if you want to replace each time and not add once and use the added/loaded fragment , use setarguments each time.... and remove previous fragment and add new fragment( with Arguments) But added once and reused is preferred instead of removing and adding/ replacing on each click
Updated2
Just initialize your TextView in onCreateView() no need to create DetailFragment with parametrize just put in comment
Check the details object whether its null or not if null initialize as you do and then called setTextView()
if(details==null)
details = new DetailFragment(index);
else
setTextView(index);
TextView inside onCreateView() and used their
public class DetailFragment extends Fragment {
String[] capitals;
int index;
private TextView textView;
public DetailFragment(int index){
this.index = index;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (container == null)
return null;
capitals = new String[] { "delhi", "karachi", "colombo", "beijing",
"dhaka", "katmandu", "Afghanistan", "pyongyang", "seoul",
"tokyo" };
View v = inflater.inflate(R.layout.detail_fragment, container, false);
// Initialize textView
textView = (TextView) v.findViewById(R.id.detailView);
setTextView(index); // set value value here for first time
return v;
}
public void setTextView(int index) {
if(textView!=null)
textView.setText(capitals[index]);
}
public int getShownIndex() {
return getArguments().getInt("index", 0);
}
}
did you tried using this
TextView view = (TextView) findViewById(R.id.detailView);
instead of this
TextView view = (TextView) getView().findViewById(R.id.detailView);