When browsing between fragment tabs in my application, the tab that I am going back to is automatically refreshed from an obsolete, to a current view. I would like to also have my application refresh the current tab after making a selection in the menubar.
What is the best way to do this? TIA
Make a update method in your fragment.
public class MyFragment extends Fragment {
public void update(){
//TODO: Do Update
}
}
Make a method like this in your MainActivity. Call it when you need to refresh the fragment.
public void refreshData(){
try {
MyFragment fragment = (MyFragment) getFragmentManager().findFragmentById(R.id.container);
fragment.update();
} catch (ClassCastException e) {
//MyFragment not active, do nothing
}
}
Got it by using FragmentManager to replace the obsolete fragment with a new one.
Now able to make a selection of an ActiveView menu item that triggers an event, and have the active fragment replaced with a current one showing this per screenshot below.
Problems getting this together were mostly related to identifying the correct R.id.layout reference to use in the FragmentManager syntax. I've posted the relevant XML and java code in hopes that others may find it useful.
MainActivity.xml
<LinearLayout 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"
android:orientation="vertical"
tools:context=".MainActivity">
<LinearLayout
**android:id="#+id/fragment_placeholder"**
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
</LinearLayout>
dataCapture.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:tag="data_capture"
android:id="#+id/data_capture"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
tools:context=".dataCapture" >
...
<TextView
style="#style/colorSizeStylexml"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dip"
android:text="Tracklog: " />
<TextView
android:id="#+id/textViewOff"
android:layout_width="40dp"
android:layout_height="40dp"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginRight="10dip"
android:text="OFF"
android:background="#ff000000"
android:textStyle="bold"
android:focusableInTouchMode="true"
android:textColor="#ffffffff" />
<TextView
android:id="#+id/textViewOn"
android:layout_width="40dp"
android:layout_height="40dp"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginRight="10dip"
android:text="ON"
android:background="#ff58ff2d"
android:textStyle="bold" />
</LinearLayout>
...
</LinearLayout>
Activity.java
public class MainActivity extends Activity{
static int iTrackLogFlag = 0; //if value = (0) Tracklog is off, if (1) Tracklog is on
public dataCapture dataCapture;
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
//put Actionbar in tab mode
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
//set titles for tabs
ActionBar.Tab dataCaptureTab = actionBar.newTab().setText("DataCapture");
ActionBar.Tab dataEditTab = actionBar.newTab().setText("DataEdit");
...
/*******************************************************************************************
* Create instances of each of the fragments. dataCapture is refreshed several times from
* fragmentManager (ActiveBar menutab for tracklog ON-OFF, and at closure of lookup table
* edit PopupWindows) hence the different format.
*******************************************************************************************/
//Fragment dataCaptureFragment = new dataCapture();
android.app.FragmentManager fragmentManager = getFragmentManager();
android.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
dataCapture dataCapture = new dataCapture();
fragmentTransaction.add(dataCapture,"data_capture");
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
Fragment dataEditFragment = new dataEdit();
...
//attach those fragment instances to their respective tabs
dataCaptureTab.setTabListener(new MyTabsListener(dataCapture));
dataEditTab.setTabListener(new MyTabsListener(dataEditFragment));
...
//add each tab to the ActionBar
actionBar.addTab(dataCaptureTab);
actionBar.addTab(dataEditTab);
...
if (savedInstanceState == null){//...do nothing
}else if (savedInstanceState != null){
actionBar.setSelectedNavigationItem(savedInstanceState.getInt(TAB_KEY_INDEX,0));
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.corax, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.menuitem_tracklogOnOff:
openTracklogDialog();//opens a dialog box...trying to minimize clutter in the toolbar.
//
return true;
}
return false;
}
private void openTracklogDialog(){
AlertDialog.Builder TracklogDialog = new AlertDialog.Builder(this);
TracklogDialog.setTitle("Tracklog control");
TracklogDialog.setMessage("Press a button below to start or stop the tracklog.");
TracklogDialog.setPositiveButton("STOP",new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
iTrackLogFlag = 0;//"0" means OFF, sets button on frontend to black w/white letters OFF
}
});
TracklogDialog.setNegativeButton("START",new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//Toast.makeText(getApplicationContext(), "Tracklog started.", Toast.LENGTH_LONG).show();
iTrackLogFlag = 1;//"1" means ON, sets button to green w/black letters
Fragment currentFragment = (dataCapture)getFragmentManager().findFragmentByTag("data_capture");
if(currentFragment == null) {
Toast.makeText(appContext, "This == NULL.", Toast.LENGTH_SHORT).show();
currentFragment = new dataCapture();
}else if(currentFragment != null){
getFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
getFragmentManager().beginTransaction().replace(R.id.fragment_placeholder, new dataCapture(),"data_capture").addToBackStack(null).commit();
Toast.makeText(appContext, "This != NULL. currentFragment = "+currentFragment+", dataCapture = "+dataCapture+".", Toast.LENGTH_LONG).show();
}
dialog.dismiss();
}
});
AlertDialog alert = TracklogDialog.create();
alert.show();
}
}
Related
I have created a DrawerLayout with a right side drawer. So far, so good. Now, there's one menu item which, when clicked opens a pop-out menu with 5 different options (see screenshot). When one of the options is clicked the icon in the main menu should get swapped for the icon that I just clicked and then the main menu should close. However, I have not been able to create that behaviour. Currently when I try to click one of the options in the pop-out menu the following happens:
1. The main menu (the drawer) closes.
2. Only if I click the desired option again the icon in the main menu gets swapped.
As far as I understand this it is the default behaviour of a drawer within a DrawerView to be closed as soon as I click somewhere in the screen. I have tried to work around it by setting the lock mode:
myDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN, Gravity.END)
... but no luck. The drawer closes as soon as I try to click one of the items in the pop-out.
Is it even possible to achieve what I want in a DrawerLayout?
Here's my code:
activity_main.xml
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="net.videosc2.activities.VideOSCMainActivity">
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/camera_preview"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:id="#+id/camera_downscaled"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:antialias="false"
android:contentDescription="#string/preview_image_content_description"
android:scaleType="fitXY"/>
</FrameLayout>
<!-- The navigation drawer that comes from the right (layout_gravity:end) -->
<ListView
android:id="#+id/drawer"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_gravity="center_vertical|end"
android:background="#99000000"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="10dp"
app:itemTextColor="#android:color/white"/>
</android.support.v4.widget.DrawerLayout>
drawer_item.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/tool"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/activatedBackgroundIndicator"
android:contentDescription="#string/a_tools_menu_item"
android:gravity="center_vertical"
android:paddingBottom="8dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:paddingTop="8dp"/>
color_mode_panel.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/color_mode_panel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginEnd="60dp"
android:layout_marginRight="60dp"
android:layout_marginTop="100dp"
android:background="#99000000"
android:clickable="true"
android:orientation="horizontal">
<ImageButton
android:id="#+id/mode_rgb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:contentDescription="#string/color_mode_rgb"
android:padding="8dp"
android:src="#drawable/rgb"/>
<ImageButton
android:id="#+id/mode_rgb_inv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:clickable="true"
android:contentDescription="#string/color_mode_rgb_neg"
android:padding="8dp"
android:src="#drawable/rgb_inv"/>
<ImageButton
android:id="#+id/mode_r"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:contentDescription="#string/color_mode_r"
android:padding="8dp"
android:src="#drawable/r"/>
<ImageButton
android:id="#+id/mode_g"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:contentDescription="#string/color_mode_g"
android:padding="8dp"
android:src="#drawable/g"/>
<ImageButton
android:id="#+id/mode_b"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:contentDescription="#string/color_mode_b"
android:padding="8dp"
android:src="#drawable/b"/>
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
static final String TAG = "MainActivity";
View camView;
public static Point dimensions;
private DrawerLayout toolsDrawerLayout;
private FrameLayout mainFrame;
private ActionBarDrawerToggle drawerToggle;
protected ArrayList<View> uiElements = new ArrayList<>();
// is device currently sending OSC?
public boolean isPlaying = false;
// is flashlight on?
public boolean isTorchOn = false;
// don't create more than one color mode panel
private boolean isColorModePanelOpen = false;
public Fragment cameraPreview;
Camera camera;
/**
* Fragment managing the behaviors, interactions and presentation of the navigation drawer.
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
final FragmentManager fragmentManager = getFragmentManager();
if (findViewById(R.id.camera_preview) != null) {
camView = findViewById(R.id.camera_preview);
if (savedInstanceState != null) return;
cameraPreview = new VideOSCCameraFragment();
fragmentManager.beginTransaction()
.replace(R.id.camera_preview, cameraPreview, "CamPreview")
.commit();
}
TypedArray tools = getResources().obtainTypedArray(drawer_icons_id);
toolsDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
toolsDrawerLayout.setScrimColor(Color.TRANSPARENT);
// FIXME: touches seem to get swallowed by the DrawerLayout first
final ListView toolsDrawerList = (ListView) findViewById(R.id.drawer);
List<BitmapDrawable> toolsList = new ArrayList<>();
for (int i = 0; i < tools.length(); i++) {
toolsList.add((BitmapDrawable) tools.getDrawable(i));
}
// set the drawer menu in a custom Adapter
toolsDrawerList.setAdapter(new ToolsMenuAdapter(this, R.layout.drawer_item, R.id.tool, toolsList));
tools.recycle();
toolsDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
BitmapDrawable img;
final ImageView imgView = (ImageView) view.findViewById(R.id.tool);
Context context = getApplicationContext();
// we can not use 'cameraPreview' to retrieve the 'mCamera' object
VideOSCCameraFragment camPreview = (VideOSCCameraFragment) fragmentManager.findFragmentByTag("CamPreview");
camera = camPreview.mCamera;
LayoutInflater inflater = getLayoutInflater();
switch (i) {
// ... other cases...
case 2:
if (!isColorModePanelOpen) {
int y = (int) view.getY();
// create pop-out
final View modePanel = inflater.inflate(R.layout.color_mode_panel, (FrameLayout) camView, true);
isColorModePanelOpen = true;
// try to lock the main menu drawer - didn't work for me
toolsDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN, toolsDrawerList);
final View modePanelInner = modePanel.findViewById(R.id.color_mode_panel);
// set the vertical position of the pop-out
ActivityHelpers.setMargins(modePanelInner, 0, y, 0, 0);
// set actions for each item in the pop-out
for (int k = 0; k < ((ViewGroup) modePanelInner).getChildCount(); k++) {
final Context iContext = context;
View button = ((ViewGroup) modePanelInner).getChildAt(k);
button.setOnClickListener(new View.OnClickListener() {
#Override
// FIXME: touches seem to get swallowed by the DrawerLayout first
public void onClick(View view) {
switch (view.getId()) {
case R.id.mode_rgb:
Log.d(TAG, "rgb");
imgView.setImageDrawable(ContextCompat.getDrawable(iContext, R.drawable.rgb));
break;
case R.id.mode_rgb_inv:
Log.d(TAG, "rgb inverted");
imgView.setImageDrawable(ContextCompat.getDrawable(iContext, R.drawable.rgb_inv));
break;
case R.id.mode_r:
Log.d(TAG, "red");
imgView.setImageDrawable(ContextCompat.getDrawable(iContext, R.drawable.r));
break;
case R.id.mode_g:
Log.d(TAG, "green");
imgView.setImageDrawable(ContextCompat.getDrawable(iContext, R.drawable.g));
break;
case R.id.mode_b:
Log.d(TAG, "blue");
imgView.setImageDrawable(ContextCompat.getDrawable(iContext, R.drawable.b));
break;
default:
imgView.setImageDrawable(ContextCompat.getDrawable(iContext, R.drawable.rgb));
}
// remove the pop-out
((ViewGroup) modePanelInner.getParent()).removeView(modePanelInner);
isColorModePanelOpen = false;
// unlock the drawer again
toolsDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, Gravity.END);
// now the drawer should finally get closed
toolsDrawerLayout.closeDrawer(Gravity.END);
}
});
}
}
break;
// ... other cases ...
}
});
// open drawer on application start
toolsDrawerLayout.openDrawer(Gravity.END);
}
}
}
Edit:
I found this post that offered me a simple way of preventing my pop-out from being closed by adding the following to my MainActivity.java:
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
// We only want to intercept MotionEvent.ACTION_UP if the pop-out is present
return !(isColorModePanelOpen && event.getAction() == MotionEvent.ACTION_UP) && super.dispatchTouchEvent(event);
}
That worked in so far as the drawer is not being closed immediately when trying to click one of the buttons in the pop-out. Unfortunately, the buttons don't accept clicks (resp. touches with an event action MotionEvent.ACTION_DOWN) either. It seems, as long as the drawer isn't closed again, the whole screen is being blocked from any user interaction.
Can anyone confirm my suspicion? (or prove me wrong)
Thanks
Try this code in onResume() of your Activity
if(condition)
{
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
}
else
{
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
}
I keep getting a crash when I change my set content view to an xml layout and not sure whats wrong. The program is supposed to have two fragments, a list view on the left and a webview on the right when it is in landscape and just the list in portrait. Sorry for all the code, I just can not figure out what is going on.
Here is my main activity
public class MainActivity extends Activity {
static final String LOGTAG = MainActivity.class.getSimpleName() + "_TAG";
static Resources mRes = null;
static FragmentManager mFrgmntMngr = null;
static MainActivity mThisAct = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentManager.enableDebugLogging(true);
setContentView(R.layout.activity_main_1view);
mRes = getResources();
mFrgmntMngr = getFragmentManager();
mThisAct = this;
}
static boolean isInLandscapeOrientation() {
return mRes.getConfiguration().orientation
== Configuration.ORIENTATION_LANDSCAPE;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void displayTwainText(int mCurPosition) {
// TODO Auto-generated method stub
if ( isInLandscapeOrientation() ) {
// Check what fragment is shown, replace if needed.
TwainTitleWebViewFragment tTxtFrgmnt = (TwainTitleWebViewFragment)
mFrgmntMngr.findFragmentById(R.id.twain_title_list);
if (tTxtFrgmnt == null || tTxtFrgmnt.getDisplayedTwainIndex() !=mCurPosition)
// Make new fragment to show this selection.
tTxtFrgmnt = TwainTitleWebViewFragment.newInstance(mCurPosition);
// Execute a transaction, replacing any existing
// fragment inside the frame with the new one.
Log.d(LOGTAG, "about to run FragmentTransaction...");
FragmentTransaction frag_trans
= mFrgmntMngr.beginTransaction();
frag_trans.setCustomAnimations(R.animator.bounce_in_down,
R.animator.fade_out);
frag_trans.setCustomAnimations(R.animator.bounce_in_down,
R.animator.slide_out_right);
frag_trans.replace(R.id.list, tTxtFrgmnt);
frag_trans.commit();
}
} else {
// Otherwise we need to launch a new activity to display
// the dialog fragment with selected text.
Intent intent = new Intent();
intent.setClass(mThisAct, TwainTitleViewActivity.class);
intent.putExtra(mRes.getString(R.string.twain_index_key), mCurPosition);
this.startActivity(intent);
}
}
}
This is activity_main1view.xml in the lay out folder
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment class="com.example.hw_07_final_.TitleListFragment"
android:id="#+id/twain_title_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
this is the one in layout-land
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment class="com.example.hw_07_final_.TitleListFragment"
android:id="#+id/list"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:background="#00550033"/>
<FrameLayout
android:id="#+id/twain_text"
android:layout_weight="4"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
this is the log cat
You CANNOT have numbers or uppercase letters when naming your xml files.
activity_main1view.xml should be activity_mainview.xml excluding "1" from the layout name.
Change
<fragment class="com.example.hw_07_final_.TitleListFragment"
To
<fragment android:name="com.example.hw_07_final_.TitleListFragment"
Run your app and it will inflate your fragment.
I'm looking to create a small flash card type element for my app. I've looked at several solutions namely the FragmentStatePagerAdapter and it's parent the FragmentPagerAdapter. Neither of these solve the problem I want to solve. They deal with listviews of fragments. I want to have a list of fragments that when I hit a button I move to the next one fragment in the list until I'm all done.
I've got all the saving the data part of it solved. I just cannot figure out how to chain my fragments together.
To be explicit, what I'm looking for is:
a->b->c->d->done and go back to activity or a finished fragment.
The user would obviously use a button to progress from fragment to fragment.
I chose fragments because I figured that would be the easiest. I'm not opposed to activities, but my problem is still largely the same.
I've tried implementing the FragmentPager stuff, but as I said it didn't suite my needs.
How dynamic are the fragments you are making? If there's a set amount of interchangeable elements, you can try creating a delegate function in your main activity that opens fragments depending on a set of parameters. Better still, you make your fragments modular so that you only have a few fragments with different states based on what you give them.
public void onCardWithIdSelected(int id, String param1, String param2, ...) {
Fragment fragment = NULL;
if(id == 0) {
fragment = cardFragment.newInstanceFromParams(param1, param2, ...); //this will pass the parameters onto the desired fragment
}
else if(id == 1) {
fragment = cardFragment.newInstanceFromParams(param1, param2, ...); //this will pass the parameters onto the desired fragment
}
else if(id == 2) {
fragment = cardFragment.newInstanceFromParams(param1, param2, ...); //this will pass the parameters onto the desired fragment
}
//and so on...
FragmentTransaction transaction = getSupportFragmentManager()
.beginTransaction();
transaction.replace(R.id.content_frame, fragment);
transaction.addToBackStack(null); //only do this if you don't want users to be able to go back
// Commit the transaction
transaction.commit();
}
Then whenever you want to move to a different fragment from one, you just call this function on the main activity with your desired parameters.
I figured out how to do this with a rather simple solution:
I have my activity which has some variables so that it knows what fragment it is on, along with that it inflates a layout with a framelayout and uses fragmentmanager transactions to replace given the fragment number we are on. Then I have a parcelable class that defines the flashcard that is passed to each fragment upon instantiation. On the activity's layout I have 3 buttons, "check", "correct", "incorrect" which, using View.GONE/View.VISIBLE am able to give the UI experience I want. On the click of the "correct"/"incorrect" we start a transaction and move down the list to the next card.
The code:
/**
* The activity
*/
public class VocabTestActivity extends Activity {
private int mWordsCorrect = 0;
private int mWordsIncorrect = 0;
private int mCurrentPosition = 0;
private ArrayList<Fragment> mCards = new ArrayList<Fragment>();
private final int FLAG_TOTAL_CARDS = 5;
private GrammarDataSource mDataSource;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_practice);
final Button buttonCheck = (Button) findViewById(R.id.buttonCheckWordPractice);
final Button buttonCorrect = (Button) findViewById(R.id.buttonCorrectWordPractice);
final Button buttonIncorrect = (Button) findViewById(R.id.buttonIncorrectWordPractice);
final TextView textViewProgressBar = (TextView) findViewById(R.id.textViewProgressBarPractice);
this.mDataSource = new GrammarDataSource(this);
this.initializeCards();
buttonCheck.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
buttonCheck.setVisibility(View.GONE);
buttonCorrect.setVisibility(View.VISIBLE);
buttonIncorrect.setVisibility(View.VISIBLE);
}
});
buttonCorrect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mWordsCorrect++;
getFragmentManager().beginTransaction().replace(
R.id.practice_frame,
mCards.get(mCurrentPosition++)
).commit();
buttonCheck.setVisibility(View.VISIBLE);
buttonCorrect.setVisibility(View.GONE);
buttonIncorrect.setVisibility(View.GONE);
textViewProgressBar.setText(getString(R.string.practice_progress_bar, mCurrentPosition, FLAG_TOTAL_CARDS));
}
});
buttonIncorrect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mWordsIncorrect++;
getFragmentManager().beginTransaction().replace(
R.id.practice_frame,
mCards.get(mCurrentPosition++)
).commit();
buttonCheck.setVisibility(View.VISIBLE);
buttonCorrect.setVisibility(View.GONE);
buttonIncorrect.setVisibility(View.GONE);
textViewProgressBar.setText(getString(R.string.practice_progress_bar, mCurrentPosition, FLAG_TOTAL_CARDS));
}
});
}
private void initializeCards() {
for(VocabWord v : this.mDataSource.selectFlashCards(FLAG_TOTAL_CARDS)) {
VocabTestFragment frag = VocabTestFragment.newInstance(new ParcelableWord(v));
mCards.add(frag);
}
}
}
/**
* The fragment
*/
public class VocabTestFragment extends Fragment {
private ViewGroup mRoot;
public final String TAG = getClass().getSimpleName();
private VocabWord mWord;
public static VocabTestFragment newInstance(ParcelableWord w) {
VocabTestFragment frag = new VocabTestFragment();
Bundle args = new Bundle();
args.putParcelable("word", w);
frag.setArguments(args);
return frag;
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
this.mRoot = (ViewGroup) inflater.inflate(R.layout.fragment_practice_vocab, container, false);
ItalianWord word = null;
ParcelableWord pw = getArguments().getParcelable("word");
pw.printIt();
word = (ItalianWord) pw.getWord();
TextView tv = (TextView) this.mRoot.findViewById(R.id.word);
if(word != null) {
tv.setText(word.getmId() + " is the id\t" + word.getmWord());
} else {
tv.setText("Word not provided");
}
return this.mRoot;
}
}
/**
* fragment_practice_vocab
*/
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="#android:drawable/gallery_thumb"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/word"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="placeholder"
android:layout_weight="4" />
</LinearLayout>
/**
* practice_activity
*/
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:padding="4dip"
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textViewProgressBarPractice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/practice_progress_bar"
/>
<FrameLayout
android:id="#+id/practice_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/textViewProgressBarPractice"
>
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="end"
android:layout_alignParentBottom="true"
>
<Button
android:id="#+id/buttonCheckWordPractice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Check"
/>
<Button
android:id="#+id/buttonCorrectWordPractice"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:visibility="gone"
android:text="Correct"
/>
<Button
android:id="#+id/buttonIncorrectWordPractice"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:visibility="gone"
android:text="Incorrect"
/>
</LinearLayout>
</RelativeLayout>
The problem is that when I click one element from the list is does not go to detail fragment view..but it work fine when it goes to landscape mode.Please tell me how can I go from list view to detail view by staying in portrait mode.
This is my list class
public class HadithList extends ListFragment
{
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
Log.d("ERROR", "In hadith list");
String[] strHadith = new String[] {"Hadith one","Hadith two","Hadith three","Hadith four"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity()
,android.R.layout.simple_list_item_1,strHadith);
setListAdapter(adapter);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
String item = (String) getListAdapter().getItem(position);
HadithDetail hadithDetail = (HadithDetail) getFragmentManager().findFragmentById(R.id.hadith_detail);
//HadithDetail hadithDetail1 = (HadithDetail) getFragmentManager().findFragmentByTag("Details");
FragmentTransaction ft = getFragmentManager().beginTransaction();
Toast.makeText(getActivity(), "Selected "+position, Toast.LENGTH_SHORT).show();
//if(hadithDetail != null && hadithDetail.isInLayout())
hadithDetail.setText(getDetails(item));
ft.replace(R.id.hadith_list, hadithDetail);
ft.commit();
}
private String getDetails(String topic)
{
if(topic.toLowerCase().contains("one"))
{
return "Here is hadith 1 detail";
}
if(topic.toLowerCase().contains("two"))
{
return "Here is hadith 2 detail";
}
if(topic.toLowerCase().contains("three"))
{
return "Here is hadith 3 detail";
}
if(topic.toLowerCase().contains("four"))
{
return "Here is hadith 4 detail";
}
return "Cannot find detail";
}
}
This is my Detail class
![public class HadithDetail extends Fragment
{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
Log.d("ERROR", "In hadith detail");
View view = inflater.inflate(R.layout.hadith_detail,container,false);
return view;
}
public void setText(String txt)
{
TextView view = (TextView) getView().findViewById(R.id.txtDetail);
view.setText(txt);
}
}][1]
Activity Main
<LinearLayout 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"
android:orientation="horizontal" >
<fragment
android:id="#+id/hadith_list"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
class="com.example.hadith_app.HadithList"
/>
</LinearLayout>
Detail Layout
<TextView
android:id="#+id/txtDetail"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal|center_vertical"
android:layout_marginTop="20dip"
android:text="Hadith 1 Detail"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="30sp"
/>
</LinearLayout>
Activity_Main.xml (Land*strong text*)
<LinearLayout 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"
android:orientation="horizontal" >
<fragment
android:id="#+id/hadith_list"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
class="com.example.hadith_app.HadithList"
/>
<fragment
android:id="#+id/hadith_detail"
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="match_parent"
class="com.example.hadith_app.HadithDetail"
/>
</LinearLayout>
First: FragmentTransaction.replace() takes the ID of a ViewGroup, not of the fragment. You need to have a ViewGroup (such as FrameLayout) in your layout XML that acts as a container for your fragments.
Second: A fragment declared statically in an XML layout cannot be removed. You need to add it programmatically when the activity is created. You can do this like so:
public class MyActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
// savedInstancState is null on the first time onCreate() runs
Fragment f = new HadithList();
getFragmentManager().beginTransaction().add(R.id.fragment_container, f).commit();
}
}
}
I believe you should read those two links first ! to see an example of how to implement the List and Details
http://www.vogella.com/articles/AndroidFragments/article.html
http://developer.android.com/guide/components/fragments.html
Some notes:
1) First of all ,you should commit your transaction in the activity.
2) Here ft.replace(R.id.hadith_list, hadithDetail); you are trying to replace your static fragment with another one. It doesn't work like this.
(I think you should get an error when you are doing that but I am not sure).
3) Dynamic Fragments should be added in a FrameLayout. And not in the sameLayout as your List.
Anyway, just check the above Links which explain very well how you should implement the List and Details Fragments and I am sure you will find what is wrong.
I can't provide a complete example because for sure it will not be as good as the examples you will find in the above tutorials.
I have this app, that I created a custom dialog for. I must of goofed something up cause while the .show call on the dialog does indeed bring it up, it looks like a whole new fragment and it is not floating but instead replacing the ui with its contents. I did see in their help for DialogFragment:
http://hi-android.info/docs/reference/android/app/DialogFragment.html#Lifecycle
that one can embed a dialog as a regular fragment or not. Though I am not doing anything to do this so I cannot figure out why its acting like an embedded fragment and not floating. After thinking on it, is it the way I defined my XML definition? The dialogfragment example above didn't really give a definition for the xml layout, so maybe that is where my issue is? (Even added the gravity to the xml file, still no dice)
My xml definition for this Dialog is here:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:textSize="20sp"
android:text = "Location:"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"/>
<Spinner
android:id="#+id/location_spinner"
android:layout_width = "450sp"
android:layout_height="wrap_content"/>
<!-- fill out the data on the package total cost etc -->
</LinearLayout>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button android:id="#+id/location_dlg_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Okay"/>
<Button android:id="#+id/location_dlg_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cancel"/>
<Button android:id="#+id/location_dlg_new"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Create new..."/>
</LinearLayout>
</LinearLayout>
Like I said displays just fine, the code for the fragment:
package com.viciousbytes.studiotab.subactivities.dialogfragments;
import ... ...
public class LocationPicker extends DialogFragment {
ArrayList<Location> mLocations;
public static LocationPicker newInstance()
{
LocationPicker loc = new LocationPicker();
return loc;
}
private void setLocations(ArrayList<Location> loc)
{
mLocations=loc;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Pick a style based on the num.
int style = DialogFragment.STYLE_NORMAL, theme = android.R.style.Theme;
setStyle(style, theme);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.location_dialog, container, false);
Spinner spinner = (Spinner)v.findViewById(R.id.location_spinner);
ArrayAdapter<Location> adapter = new ArrayAdapter<Location>(v.getContext(), android.R.layout.simple_spinner_item, mLocations);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
if(mLocations==null)
spinner.setPrompt("No Locations");
else
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new LocationSelectedListener());
// Watch for button clicks.
Button newBtn = (Button)v.findViewById(R.id.location_dlg_new);
newBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// When button is clicked, call up to owning activity.
//create new start that activity...
}
});
// Cancel do nothing dismissthis
Button cancelBtn = (Button)v.findViewById(R.id.location_dlg_cancel);
cancelBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// When button is clicked, call up to owning activity.
//create new start that activity...
}
});
// okay button means set listener with the selected location.
Button okBtn = (Button)v.findViewById(R.id.location_dlg_ok);
okBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// When button is clicked, call up to owning activity.
//create new start that activity...
}
});
return v;
}
}
It is called from a fragment itself? though does that matter? because I am calling a TimePIckerDialog and a DatePickerDialog and those work fine, but my calling code from my other fragment is:
void showLocationDialog() {
FragmentTransaction ft = getFragmentManager().beginTransaction();
Fragment prev = getFragmentManager().findFragmentByTag("locpicker");
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
// Create and show the dialog.
DialogFragment newFragment = LocationPicker.newInstance();
newFragment.show(ft, "locpicker");
}
Your constructors are wrong. Try to have just one static method newInstance to instantiate the fragment for all cases and use a Bundle to store the arguments that you want to use in the fragment. Refer to Basic Dialog section here and extend it to your case.