I am creating an activity that implements a fragment list and a regular fragment showing details of the list. i am having a VERY hard time trying to take the android developer tutorial on fragment cursor and use it.
I am trying to load the title's from my SQLdatabse into the fragment list. And when the item is clicked show details for it. I know i will just store the id of the item in a extra and pick it out in the details fragment to get the information.
Im just kind of confused on the whole ListFragment class.
Here is my source code where im at so far...
public class Main extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentManager fm = new getFragmentManager();
if(fm.findFragmentById(android.R.id.content)== null){
CursorLoaderListFragment list = new CursorLoaderListFragment();
fm.beginTransaction().add(android.R.id.content, list).commit();
}
}
public static class CursorLoaderListFragment extends ListFragment{
SimpleCursorAdapter mAdapter;
String mCurFilter;
#Override
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
setEmptyText("No Task");
setHasOptionsMenu(true);
}
}
}
If someone has a better way than what im doing PLEASE let me know and provide an example.
Thanks!
Related
Unlike typical android projects starting with MainActivity with all the code of the layout object in it. This architecture requires me to have the initial code in a custom object. Here's a structure for better understanding.
java/MainActivity.java
java/User.java
layout/activity_main.xml
layout/user.xml
Now I also need a reference to User object within MainActivity and it looks like this.
public class MainActivity extends AppCompatActivity {
public Users users; // instantiate custom class and show
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
My User class looks like this.
public class User extends AppCompatActivity {
ListView userList;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.user_list, container, false); // Inflate the layout for this fragment
userList = view.findViewById(R.id.userList);
return view;
}
}
layout/user.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="org.puremvc.java.demos.android.employeeadmin.view.components.UserList">
<ListView
android:id="#+id/userList"
android:layout_width="395dp"
android:layout_height="715dp"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="8dp" />
</FrameLayout>
So, in other words, MainActivity just acts like a stage doing nothing except just providing a reference to the Initial object. Now I do need MainActivity to be there, can't point User to be a launcher in the manifest. Responsibilities are to be taken care of by User class.
Question: How to instantiate CustomClass User and show.
Context: The MainActivity class has to be minimalistic and clean, no User related code (ListView), all logic lies in the custom class.
P.S. There can be lateral approaches, as long as I have a reference to user Object in MainActivity and it's displayed on launch, I'll accept the answer.
As per my understanding: there should be two approaches.
First, by using the Fragment inside your Activity. Write all initialize and data flow codes inside the fragment and just initialize and start the fragment from the Activity. So when the Activity will start, it will give all its tasks to the fragment with its Context and rest thing Fragment will do.
Like below:
public class MainActivity extends AppCompatActivity {
public Users users; // instantiate custom class and show
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//the fragment stuff
FragmentManager fm= getFragmentManager() //or get SupportFragmentManager when the Fragment comes from Support lib
FragmentTransaction ft= fm.beginTransaction();
Fragment fragment= new UserListFragment();
ft.add(R.id.fragment_container, fragment);
ft.commit();
}
}
OR, the second approach should by using Interface and communicate both Activity and the Custom Class (or you can call it Controller) with it.
Its nothing, but a simple MVC design pattern which I never recommend.
You can write one Interface like below:
public interface IController{
public void initialize(Activity activity, Bundle savedInstanceState);
public void engage();
public void disengage();
}
Then, make an instance of this Controller inside your Activity/BaseActivity and use like below:
public MainActivity(IController controller){
this.controller = controller;
}
Then call each callback methods from their appropriate place to make them work inside the Controller.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//give the priviledge of onCreate to initialize
controller.initialize(this, savedInstanceState);
}
Then in your Controller class, just write the same program which you supposed to write inside Activity:
public class Your_Controller implements IController {
#Override
public void initialize(Activity activity, Bundle savedInstanceState) {
//do super where needed
//make one class level Activity instance to work in other methods
act = activity;
//just initialize views like below
TextView tv = (TextView) activity.findViewById(R.id.abc);
}
I have listview in one fragment that displays item from a sqlite database. When I click on one item it opens a menu to allow to open, add to another listview or delete. I want to be able to add it to another listview in another fragment on press. I tried adding it to another listview using bundles but I had no luck. I have a plan of creating another database table to store the added data and display it in a new listview. Would this work? or do any of you guys have another suggestion?
You can send data from one fragment to another. The best way to do this is by going through the parent activity. Something like this:
public class MyActivity extends FragmentActivity implements MyFragmentListener {
MyFragment1 frag1;
MyFragment2 frag2;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(0);
FragmentManager fm = getSupportFragmentManager();
frag1 = (MyFragment1) fm.findFragmentByTag("frag1");
frag1.setListener(this);
frag2 = (MyFragment2) fm.findFragmentByTag("frag2");
}
// Call this function from frag1 when you want to send the data to frag2
public void addToFrag2(ListItem item) {
frag2.addToList(item);
}
}
// Define whatever methods the fragments want to use to pass data back and forth
public interface MyFragmentListener {
void addToFrag2(ListItem item);
}
Basically I've got an ActionBarActivity that loads activity_main.xml which contains my ListFragment
My ActionBar has an Add button on it, to add items to the list.
Problem I've run into now, is how do I handle the Add and pass the information to the ListFragment to populate the ListView?
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//activity_main only contains <fragment ... /> to add my ListFragment
}
....
// This is called from onOptionsItemSelected
private void showAddDialog() {
FragmentManager fm = getSupportFragmentManager();
InputDialog inputDialog = new AddInputDialog();
inputDialog.setOnUpdateListener(new InputDialog.onUpdateListener(){
#Override
public void onUpdate(Item item){
//I'm lost at what to do here...
}
});
inputDialog.show(fm, "fragment_dialog_input");
}
EDIT
Got it working using findFragmentById(), and posted answer below.
I kept trying to get it to work using findFragmentByTag() and even though I had a TAG set in my fragment, and when debugging it(the TAG) showed correctly, for some reason would always return null.
Since the fragment is defined in activity_main.xml use findFragmentById using the specified android:id then you can call your public function within the ListFragment to update the list and notify adapter.
private void showAddDialog() {
final FragmentManager fm = getSupportFragmentManager();
InputDialog inputDialog = new AddInputDialog();
inputDialog.setOnUpdateListener(new InputDialog.onUpdateListener(){
#Override
public void onUpdate(Item item){
ListFragment lf = (ListFragment)fm.findFragmentById(R.id.listFragment);
lf.addItem(item);
}
});
inputDialog.show(fm, "fragment_dialog_input");
}
I am creating a survey app based on WizarDroid. I am using a ViewPager and the questions are loaded dynamically in each fragment in the ViewPager.
The ViewPager creates 3 fragments: "Pre", "Current" and "Next".
I am having a problem with the "Next" fragment because my last fragment is a ListFragment (AnswerReviewList) so the list cannot update the last question and answer because it is already created.
Is it possible to refresh the list (ReviewListfragment) from a ViewPager listener method?
#Override
public void onPageSelected(int position) {}
Please ask if you don't understand my question.
ReviewListFragment.java
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.i("############################ last fragment ",
"onActivityCreated");
queArrListVO = ((EventSurveyActivity) getActivity()).surveyQuetionVOList;
adptrReviewQuestion = new SurveysReviewBaseAdapter(
getSherlockActivity(), queArrListVO);
getListView().setAdapter(adptrReviewQuestion);
getListView().setOnItemClickListener(this);
setEmptyText(" :) ");
setListShown(true);
}
If your SurveysReviewBaseAdapter extends from BaseAdapter (which I'll assume given the name of the class), you can use BaseAdapter.notifyDatasetChanged to reload the ListAdapter with the new data in, for example, onResume.
I am trying to implement a ListFragment. The idea is to use CursorLoader. The code for FragmentActivity is
public class XYZ extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentManager fm = getSupportFragmentManager();
// Create the list fragment and add it as our sole content.
if (fm.findFragmentById(android.R.id.content) == null) {
XYZFragment list = new XYZFragment();
fm.beginTransaction().add(android.R.id.content, list).commit();
}
}
Now I assume that onActivityCreate of XYZFragment should be called but that is not happening instead I am getting a the below image on the Emulator. I am looking for an explanation as to what is happening and what I am doing wrong?
Thanks.
Change onActivityCreate to onActivityCreated and you should get the expected results.