Confused as to why the onClickListener is not responding. Is it because but buttons are set in one layout, but bound to another one? Any help would be appreciated.
public class ActivityList extends ListFragment
{
private ActivityDbAdapter mDbHelper;
private Long mRowId=Long.valueOf(1);
private Activity mContext; //changed to private
AlertDialog activity_relationship;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mContext=this.getActivity();
mDbHelper=new ActivityDbAdapter(mContext);
mDbHelper.open();
Cursor activity = mDbHelper.fetchAll(mRowId);
View view = (View) inflater.inflate(R.layout.activity_activity_row, container,false);
Button relationship = (Button) view.findViewById(R.id.show_relationship_activities);
String[] from = new String[]{ActivityDbAdapter.COLUMN_NAME_VALUE1_RELATIONSHIP , //from and too.
ActivityDbAdapter.COLUMN_NAME_VALUE1_EDUCATION,
ActivityDbAdapter.COLUMN_NAME_VALUE1_RECREATION,
ActivityDbAdapter.COLUMN_NAME_VALUE1_MIND, ActivityDbAdapter.COLUMN_NAME_VALUE1_DAILY};
int[] to = new int[]{R.id.relationship_value,R.id.education_value, R.id.recreation_value,
R.id.mind_value, R.id.daily_value};
SimpleCursorAdapter contacts =
new SimpleCursorAdapter(mContext, R.layout.activity_activity_row, activity, from, to); //my cursor adapter
relationship.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg) {
Log.e("Why","Are you not working?");
Cursor activity = mDbHelper.fetchAll(mRowId);
String mactivity_relationship=activity.getString( //define all of the Strings. Gahh!!
activity.getColumnIndexOrThrow(ActivityDbAdapter.COLUMN_NAME_ACTIVITY1_RELATIONSHIP));
AlertDialog activity_relationship=new AlertDialog.Builder(mContext).create();
activity_relationship.setTitle("Relationship Activities");
String activities=(mactivity_relationship+"\n"+mactivity_relationship2+"\n"+mactivity_relationship3+
"\n"+mactivity_relationship4+"\n"+mactivity_relationship5);
activity_relationship.setMessage(activities);
activity_relationship.show();
}
});
setListAdapter(contacts);
return inflater.inflate(R.layout.activity_activity_list, container, false);
}
}
As I have it right now, the log is not even showing up.
You may want to return the view that you actually create(and use for getting the Button) in the onCreateView:
//...
return view;
instead of returning a newly inflated layout(and losing the previous Button):
return inflater.inflate(R.layout.activity_activity_list, container, false);
Or add the view to a view from the R.layout.activity_activity_list file that you inflate and return.
Related
I used the same code in Activity and it works. But the same thing does not work in Fragment. I have placed some tests to check if the DB is created correctly and found the cursor is filled with data.
Here is the code:
public class Db_fragment extends Fragment {
View view;
ListView listView;
Db_listView_Adapter db_listView_adapter;
public Db_fragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.db_fragment, container, false);
return view;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final MyDatabaseOpenHelper mDbHelper = new MyDatabaseOpenHelper(view.getContext());
final EditText foodName = (EditText) view.findViewById(R.id.nameForDb);
Button enterData = (Button) view.findViewById(R.id.enterData);
Button showData = (Button) view.findViewById(R.id.showData);
enterData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
SQLiteDatabase myDb = mDbHelper.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(TableFoodMacros.FoodMacros.FOOD_NAME,foodName.getText().toString());
long newRowId ;
newRowId = myDb.insert(TableFoodMacros.FoodMacros.TABLE_NAME,null,contentValues);
Log.e("TEST1","TEST INSERT " + String.valueOf(newRowId));
}
});
showData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
SQLiteDatabase myDb = mDbHelper.getReadableDatabase();
String[] projection = {"_id",TableFoodMacros.FoodMacros.FOOD_NAME};
Cursor c = myDb.query(
TableFoodMacros.FoodMacros.TABLE_NAME,
projection,
null,
null,
null,
null,
null,
null
);
Log.e("TEST3", String.valueOf(c.getCount()));
listView = (ListView) view.findViewById(R.id.dbView);
db_listView_adapter = new Db_listView_Adapter(view.getContext(),c);
listView.setAdapter(db_listView_adapter);
}
});
}
}
The app crashes on this line :
listView.setAdapter(db_listView_adapter);
You need to remove the findViewById of the dbView from the onClickListener of showData and place it in the onCreateView.
So remove the following.
showData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// ... Remove the following code segment from here.
listView = (ListView) view.findViewById(R.id.dbView);
db_listView_adapter = new Db_listView_Adapter(view.getContext(),c);
listView.setAdapter(db_listView_adapter);
}
});
Place the code segment in your onCreateView function.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.db_fragment, container, false);
// Place the code segment here
listView = (ListView) view.findViewById(R.id.dbView);
db_listView_adapter = new Db_listView_Adapter(view.getContext(),c);
listView.setAdapter(db_listView_adapter);
return view;
}
It works in your Activity as you don't have find the ListView id in the View returned. Once you set the content view of your Activity you can place findViewById anywhere and it'll find the associated layout reference perfectly.
In case of Fragment, as you see the onCreateView function returns a View object as the reference of the View which is inflated. So you need to find your ListView in that View. That's why you need to put view.findViewById to search for reference id of the ListView in that View which is inflated.
When you're putting the listView = (ListView) view.findViewById(R.id.dbView); inside the showData.setOnClickListener it gets the reference of the button showData and tries to find the dbView in that Button view which causes the error.
So its necessary to get the reference of your list inside onCreateView and set the adapter there. You can then easily call notifyDatasetChanged() to reload your list when the cursor is filled with data.
By the way, you may put the code segment in your onViewCreated function too as you see you could get the reference of the showData button from there without any problem. So you can even put the code segment there too.
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final MyDatabaseOpenHelper mDbHelper = new MyDatabaseOpenHelper(view.getContext());
final EditText foodName = (EditText) view.findViewById(R.id.nameForDb);
Button enterData = (Button) view.findViewById(R.id.enterData);
Button showData = (Button) view.findViewById(R.id.showData);
// You can place the code segment here too
listView = (ListView) view.findViewById(R.id.dbView);
db_listView_adapter = new Db_listView_Adapter(view.getContext(),c);
listView.setAdapter(db_listView_adapter);
// ... Other code goes here.
}
And you might modify the showData.setOnClickListener like this
showData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
SQLiteDatabase myDb = mDbHelper.getReadableDatabase();
String[] projection = {"_id",TableFoodMacros.FoodMacros.FOOD_NAME};
Cursor c = myDb.query(
TableFoodMacros.FoodMacros.TABLE_NAME,
projection,
null,
null,
null,
null,
null,
null
);
Log.e("TEST3", String.valueOf(c.getCount()));
// Call notifyDatasetChanged when the cursor is filled with data to load the list.
db_listView_adapter.notifyDatasetChanged();
}
});
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 have a Spinner in my class TelaEntrada.java loading normally.
public class TelaEntrada extends Fragment {
public Fragment newInstance(Context context) {
TelaEntrada telaEntrada = new TelaEntrada();
return telaEntrada;
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.telaentrada, container, false);
DbEntrada banco = new DbEntrada(getActivity().getApplicationContext());
List<Tipo> tipos = banco.todosTipos();
List<String> item = new ArrayList<String>();
for(Tipo tipo : tipos){
item.add(tipo.getDescricao().toString());
}
final Spinner spn_Entrada = (Spinner) root.findViewById(R.id.spnEntradaTipo);
ArrayAdapter<String> adapter2 = new ArrayAdapter<String>(
this.getActivity(),
android.R.layout.simple_spinner_dropdown_item, item);
spn_Entrada.setAdapter(adapter2);
I too have one DialogFragment in another class. Code is below.
public class DialogTipo extends DialogFragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
final View root = (View) inflater.inflate(R.layout.dialog_tipo, container, false);
final EditText txtDialogTipo = (EditText)root.findViewById(R.id.txtDialogTipo);
Button btnDialogTipoAdd = (Button) root.findViewById(R.id.btnDialogTipoAdd);
Button btnDialogTipoCancel = (Button) root.findViewById(R.id.btnDialogTipoCancel);
btnDialogTipoAdd.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
DbEntrada banco = new DbEntrada(getActivity().getApplicationContext());
banco.insereTipo(txtDialogTipo.getText().toString());
//I want update my spinner here!
dismiss();
}
});
getDialog().setTitle("Inserir Novo Tipo");
return root;
}
}
I wanted to add a new item, the spinner was directly updated the database to display the new information in the User spinner. Thanks. Sorry for my english!
In general most of the time I work with Intent rather than Fragment because I found It somehow complex. I have a class with ListView to show some data from an array and I want to convert it in Fragment also want to pass the extras in a new fragmented class.
ListView Class:
public class MainActivity extends Activity {
ListView list;
String[] web = { "Google", "Twitter", "Windows", "Bing", "Itunes",
"Wordpress", "Drupal" };
Integer[] imageId = { R.drawable.ic_launcher, R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher,
R.drawable.ic_launcher
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CustomList adapter = new CustomList(MainActivity.this, web, imageId);
list = (ListView) findViewById(R.id.list);
list.setAdapter(adapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(MainActivity.this,
"You Clicked at " + web[+position], Toast.LENGTH_SHORT)
.show();
Intent i = new Intent(MainActivity.this, intent.class);
i.putExtra("name", web[+position]);
startActivity(i);
}
});
}
}
CustomList Class:
public class CustomList extends ArrayAdapter<String> {
private final Activity context;
private final String[] web;
private final Integer[] imageId;
public CustomList(Activity context, String[] web, Integer[] imageId) {
super(context, R.layout.list_single, web);
this.context = context;
this.web = web;
this.imageId = imageId;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView = inflater.inflate(R.layout.list_single, null, true);
TextView txtTitle = (TextView) rowView.findViewById(R.id.txt);
ImageView imageView = (ImageView) rowView.findViewById(R.id.img);
txtTitle.setText(web[position]);
imageView.setImageResource(imageId[position]);
return rowView;
}
}
I got a main class with three tabs created using fragment and in this class I would like to add the ListView!
public class LayoutOne extends Fragment {
public static Fragment newInstance(Context context) {
LayoutOne f = new LayoutOne();
return f;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.layout_one, null);
return root;
}
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
}
}
What I want to do is to show the listview in the fragment class and when a list item will be click I want to launch the New Intent to show which Item was clicked!
If you want to pass parameters into a Fragment, common practice is to create a static method that produces an instance of your Fragment with certain parameters. You already have the newInstance method, now you just need to add parameters to the arguments and return the Fragment. You should check for the arguments in your onCreateView The following is an example of how you would write one.
public class LayoutOne extends Fragment
{
public static Fragment newInstance(int someInt, String someString)
{
LayoutOne f = new LayoutOne();
Bundle args = new Bundle();
args.putInt("someInt", someInt);
args.putString("someString", someString);
f.setArguments(args);
return f;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
{
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.layout_one, null);
Bundle args = getArguments();
//From here you would check to see if your arguments are present
//proceed accordingly
return root;
}
}
For your specific case, you could pass along the String array and add it as an argument.
Hope this helps. Good luck!
Edit
The problem you're facing is that you're instantiating a ListView in your Activity when in reality you should be doing it in your Fragment. Intents aren't needed here, you just need to make sure that there is a ListView attribute to get from the layout you attach to your Fragment. The following is a small example of how that should work.
Note, this method goes in your LayoutOne class
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
{
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.layout_one, null);
//Be sure to use the actual id of your list view
ListView lv = (ListView) root.findViewById(R.id.list_view_id);
//Make sure that you retrieve the values for 'web' and 'imageId' from
//the activity using the "newInstance" method.
CustomList adapter = new CustomList(getActivity(), web, imageId);
lv.setAdapter(adapter);
//From here, set your onClickListener and stuff as you did in your Activity
return root;
}
As a note, Fragments don't have the findViewById method. You have to call it on the View that you are inflating to be its layout, so in this case you inflated root and then you would call root.findViewById(R.id.some_id) to get a view.
Inside a fragment, I have a button which I want to "trigger" the filling of a Listview from a database, using a Cursor Adapter.
The code for the fragment goes something like this:
public class TabFragment6 extends ListFragment {
/** (non-Javadoc)
* #see android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LinearLayout Layout6 = (LinearLayout) inflater.inflate(R.layout.tab_frag6_layout, container, false);
// Register for the Button.OnClick event
Button bShopGuit = (Button)Layout6.findViewById(R.id.buttonshopguit);
bShopGuit.setOnClickListener(new View.OnClickListener() { //abre setonclicklistener(
#Override
public void onClick(View v) {
Cursor allItems;
MyDatabase db;
Context ctx = (Context)TabFragment6.this.getActivity();
db = new MyDatabase(ctx);
allItems = db.getGuitarItems();
ListAdapter adapter = new SimpleCursorAdapter (ctx,
android.R.layout.simple_list_item_1,
allItems,
new String[] {"ItemName"},
new int[] {android.R.id.text1});
getListView().setAdapter(adapter);
}
}); //fecha )
return Layout6;
}
However, I'm getting an error in the adapter: The method getactivity() is undefined for the type new View.OnClickListener(){}
How can I fix this? Thanks!!
use this db = new MyDatabase(getActivity()); instead of Context ctx = (Context)TabFragment6.this.getActivity(); and db = new MyDatabase(ctx);
You cannot call getActivity() in the new View.OnClickListener() { interface
for it doesn't have this method there. you may probably want to create final reference
to your activity and use it within your onClick() method.
You are creating a new anonymous class which implements View.OnClickListener interface which
doesn't have getActivity() method.
should be something like this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LinearLayout Layout6 = (LinearLayout) inflater.inflate(R.layout.tab_frag6_layout, container, false);
final Activity activity = this.getActivity(); //this will call your tabfragment's associated activity
............
//and in your onClick()
db = new MyDatabase(activity); // or try to use the Contexts or cast to them depends on your constructor parameters
hope it helps