AndroidPlot graph disappears on landscape view in Fragment - android

I am using AndroidPlot for displaying dynamic data on a graph in my android App. The graph is displayed in a fragment, which is a part of a tabbed screen (view pager). The graph needs to be displayed in landscape and portrait mode.
When the graph is displayed on the portrait mode, I can see it properly. However, when the phone is turned into landscape mode, the graph disappears completely. This happens only when the AndroidPlot graph is used in a Fragment. When AndroidPlot graph is used in an activity directly without fragment, the graph is displayed correctly in landscape and portrait mode.
Has anyone experienced this? Any help in resolving this issue is appreciated.
My layout.xml file is as follows:
<RelativeLayout 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="com.monitrahealth.mhsmartmct.TestFragment" android:id="#+id/fragment_test">
<com.androidplot.xy.XYPlot
android:id="#+id/mplot"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="4"
androidplot.renderMode="use_background_thread"
androidPlot.titleWidget.labelPaint.textSize="#dimen/title_font_size"
androidPlot.domainLabelWidget.visible="false"
androidPlot.domainLabelWidget.labelPaint.textSize="#dimen/domain_label_font_size"
androidPlot.rangeLabelWidget.visible="false"
androidPlot.rangeLabelWidget.labelPaint.textSize="#dimen/range_label_font_size"
androidPlot.graphWidget.marginTop="0dp"
androidPlot.graphWidget.marginLeft="0dp"
androidPlot.graphWidget.marginBottom="0dp"
androidPlot.graphWidget.marginRight="0dp"
androidPlot.graphWidget.rangeLabelPaint.textSize="#dimen/range_tick_label_font_size"
androidPlot.graphWidget.rangeOriginLabelPaint.textSize="#dimen/range_tick_label_font_size"
androidPlot.graphWidget.domainLabelPaint.textSize="#dimen/domain_tick_label_font_size"
androidPlot.graphWidget.domainOriginLabelPaint.textSize="#dimen/domain_tick_label_font_size"
/>
And my Fragment code is as follows:
public class TestFragment extends android.support.v4.app.Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View ecgGraphView = inflater.inflate(R.layout.fragment_ecggraph, container, false);
XYPlot dynamicPlot = (XYPlot) ecgGraphView.findViewById(R.id.dynamicXYPlot);
return ecgGraphView;
}
public void onPause() {
super.onPause();
}
public void onDestroy(){
super.onDestroy();
}
#Override
public void onResume() {
super.onResume();
}}

Related

Android TV Leanback

I am new to Android TV development. I don't know which type of fragment to use. I want two achieve layout similar to above screenshot as jiocinema. Somehow I have achieved it using a two xml fragments inside activity layout. Second fragments loads screenshot after hitting an API so it loads after some time. As can be seen in the above screenshot I want the layout in two parts..top one with details and some buttons and the bottom one is a list of screenshots of that movie.
In my case the problem is, bottom list part takes the focus on loading this particular screen after that on pressing up button or any button it never loses focus and never goes on the top part.
Note: below fragment loads asynchronously, as it hits an api for screenshot urls
May be I haven't used proper fragments for this particular layout. Can someone point me to the code or help me out in deciding what to use for this kind of layout. As it can be achieved but navigation is the main thing.
code
activity layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/photo_label_box">
<fragment
android:id="#+id/detail_layout"
android:layout_width="match_parent"
android:name="com.DetailsActivityGame$Detalfragment"
android:layout_height="200dp"></fragment>
<fragment
android:id="#+id/row_layout"
android:layout_width="match_parent"
android:layout_below="#+id/detail_layout"
android:name="com.DetailsActivityGame$SampleFragmentC"
android:layout_height="wrap_content"></fragment>
</RelativeLayout>
Thanks
Try to use the RowSupportFragment in V4 Support Fragment for desired output.
Divide layout into two parts layout with buttons, description and below scrolling layout(Represent by RowSupportFragment)
//----------------------detail_layout
<?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"
android:background="#color/leader_background">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/main_layout"
//your own layout design for buttons and description
</RelativeLayout>
<fragment
android:name="FragmentScreenshots"
android:id="#+id/screenshot_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
//----------------Detailfragment--------------------
public static class Detailfragment extends Fragment {
public Detailfragment(){ }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.detail_layout, container, false);
//————————your own implementation—————————————————————————
return view;
}
public static class FragmentScreenshots extends RowsSupportFragment {
private ArrayObjectAdapter mRowsAdapter = null;
public FragmentScreenshots() {
mRowsAdapter = new ArrayObjectAdapter(new ShadowRowPresenterSelector());
setAdapter(mRowsAdapter);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//———————Provide data accordinally———————————
List<ScreenshotItem> list;
// Add a Related items row
ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(
new ScreenshotCardPresenter(getActivity()));
for (ScreenshotItem s:list)
{
listRowAdapter.add(s);
}
HeaderItem header = new HeaderItem("Screenshots");
mRowsAdapter.add(new ListRow(header, listRowAdapter));
setAdapter(mRowsAdapter);
setOnItemViewClickedListener(new OnItemViewClickedListener() {
#Override
public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row) {
if (item instanceof ScreenshotItem) {
}
else{
}
}
});
setOnItemViewSelectedListener(new OnItemViewSelectedListener() {
#Override
public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row) {
}
});
}
#Override
public void setExpand(boolean expand) {
super.setExpand(true);
}
#Override
public void setOnItemViewClickedListener(BaseOnItemViewClickedListener listener) {
super.setOnItemViewClickedListener(listener);
}
#Override
public void setOnItemViewSelectedListener(BaseOnItemViewSelectedListener listener) {
super.setOnItemViewSelectedListener(listener);
}
}}
You have to use BrowseFragment for your purpose. It is composed of a RowsFragment and a HeadersFragment.
A BrowseFragment renders the elements of its ObjectAdapter as a set of rows in a vertical list. The elements in this adapter must be subclasses of Row.
This tutorial can help you to get started.

How to change fragment position when rotate device

I want to change from layout 1 to layout 2, after rotate still keep content. Can somebody show me how to do that?
from this: https://www.dropbox.com/sc/y2nyrzard859hf2/AAD0qVjWoLzKcnQV9a4FTQi_a
to this: https://www.dropbox.com/sc/29hhlbfm31cfs0j/AADCWsFNzD7DKHx4q9i2FlbDa
this is my code but seem like it didn't work
if(config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
setContentView(R.layout.activity_create_bill3);
}
else {
setContentView(R.layout.activity_create_bill2);
}
if(fragmentManager.findFragmentByTag("fragment_product")==null) {
fragment_product = new Fragment_Product();
fragmentTransaction.replace(R.id.fragment_product,fragment_product,"fragment_product");
}
else
fragmentTransaction.replace(R.id.fragment_product,fragmentManager.findFragmentByTag("fragment_product"));
if(fragmentManager.findFragmentByTag("fragment_product_chosen")==null) {
fragment_product_chosen = new Fragment_Product_Chosen();
fragmentTransaction.replace(R.id.fragment_product_chosen,fragment_product_chosen,"fragment_product_chosen");
}
else
fragmentTransaction.replace(R.id.fragment_product_chosen,fragmentManager.findFragmentByTag("fragment_product_chosen"),"fragment_product_chosen");
fragmentTransaction.commit();
I using 2 diffent layout, it has a same view but one in horizontal and another in vertical, when rotate, fragment_product still keep content, but fragment_product_chosen are disappear.
You should have 3 clases:
FragmentMain
FragmentSide
MainActivity
click here to see your layout folder
Code in your MainActivity Class:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
Code in your FragmentMain Class:
public class FragmentMain extends Fragment{
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main, container, false);
}
}
Code in your FragmentSide Class:
public class FragmentSide extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_side, container, false);
}
}
Then in your activity_main.xml:
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragment_main"
android:layout_marginTop="230dp"
class="au.com.example.multi_fragments.FragmentMain" />
<fragment
android:layout_width="match_parent"
android:layout_height="220dp"
android:id="#+id/fragment_side"
class="au.com.example.multi_fragments.FragmentSide" />
/>
same way in your activity_main.xml(land):
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="250dp"
android:id="#+id/fragment_main"
class="au.com.example.multi_fragments.FragmentMain" />
<fragment
android:layout_width="240dp"
android:layout_height="match_parent"
android:id="#+id/fragment_side"
class="au.com.example.multi_fragments.FragmentSide" />
in your fragment_main.xml:
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="View 2"
android:textSize="20sp"
android:padding="20dp"
android:textStyle="bold"
android:id="#+id/textViewMain" />
In your fragment_side.xml:
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="View 1"
android:textSize="20sp"
android:padding="20dp"
android:textStyle="bold"
android:id="#+id/textViewMain" />
Click here to see the output
I hope this solution is the one you want. Good luck :)
To have different layouts for landscape and portrait modes, create two folders under the res folder: layout and layout-land. All XML files should have the same names in both folders. For more details, read Designing for Multiple Screens. Even though this article is for different screen sizes, the techniques apply to different device orientations as well.
As for saving and restoring data, this is the same as destroying the activity without an orientation change.

Hide/Show Button in Fragment from Activity

i am trying to hide/show Button in fragment from Activity but it give me following exception.
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
Home Activity
public class HomeActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
CategoryFragment frag=(CategoryFragment) activity.getSupportFragmentManager()
.findFragmentByTag("cat_frag");
Button newDesigns= (Button) frag.getView().findViewById(R.id.new_designs);
newDesigns.setVisibility(View.VISIBLE);
}
}
Category Fragment
public class CategoryFragment extends Fragment{
Button newDesigns;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_category, null);
newDesigns= (Button) v.findViewById(R.id.new_designs);
}
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CCCCCC">
<TextView
android:id="#+id/list_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:background="#drawable/shape_logo_bg"
android:gravity="center"
android:padding="5dp"
android:textColor="#android:color/white"
android:textSize="18sp" />
<Button
android:id="#+id/new_designs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/list_name"
android:background="#color/edit_button_color"
android:padding="10dp"
android:text="#string/new_designs"
android:textColor="#color/btn_text_color"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dp"
android:visibility="gone"
/>
</RelativeLayout>
Code is too large to be posted here. Thats why i have only posted the code where i am finding an issue.
I am able to get newDesigns BUTTON instance.What is shocking for me is if try to play with button instance (VISIBLE/GONE) it gives me above mentioned exception.
Help is appreciated.
You shouldn't play with a view of the Fragment while you are in a Activity directly. You will not know what the view's state will be and this can potentially lead to issues you can't even think of(beleive me i faced many). To interact with the activity's views, make an interface:
public interface AccessFragmentViews{
public void setVisibilityForButton(boolean bool);
//any other methods that you need
}
Now implement this inside the fragment class and override the method.
class YourFragment implements AccessFragmentViews{
.
.
public void serVisibilityForButton(boolean shouldHide){
if(shouldHide){
yourButton.setVisibility(View.GONE);
}else{
yourButton.setVisibility(View.VISIBLE);
}
}
}
Now you can interact safely with the views of the fragment within a activity using this interface. Make sure that the fragment is alive before doing so though ;) accessing child's view are prone to WindowLeakedExceptions and illegalstateexceptions
In the activity use it as follows:
you can get the fragment reference by either finding it by its tag or by using the reference you used to create the fragment
//NOTE: it is very very dangerous to do the accessing on a fragment views from an activity
//first the alive check then the logic
if(yourFragmentReference!=null){
((AccessFragmentViews)yourFragmentReference).setVisibilityForButton(true);// or false if you want to make it visible
}
Add a method in your fragment class
public void changeButtonVisibility(boolean visibility){
if(visibility){
newDesigns.setVisibility(View.VISIBLE);
}else{
newDesigns.setVisibilty(View.GONE);
}
}
and in your activity class
add this line
public class HomeActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
CategoryFragment frag=(CategoryFragment) activity.getSupportFragmentManager()
.findFragmentByTag("cat_frag");
frag.changeButtonVisibility(true);
}
}

Android MapView disappears using a ViewPager and PageTransformer

I'm having trouble setting up a ViewPager using a PageTransformer and a MapView. The problem is when the viewpager is set to use the PageTransformer, the mapview disappears(goes transparent) while panning. However, if I don't use a transformer and just pan the Mapview is fine. Does anyone know what is causing this behavior?
Currently the PageTransformer does nothing special but just setting it seems to affect the way the mapview is drawn. I should note that the map goes transparent while the mapview(Legal Notice)remains. When the ViewPager enters an Idle state the Map appears.
viewPager.setPageTransformer(true, this);
...
#Override
public void transformPage(View view, float position) {
}
XML: ViewPager Fragment
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF">
<com.google.android.gms.maps.MapView
android:id="#+id/mapcontainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="false"/>
</FrameLayout>
Map Fragment:
private GoogleMap map;
private MapView mapView;
private Bundle mapBundle;
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
mapBundle = savedInstanceState;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.mapfragment, container, false);
MapsInitializer.initialize(getActivity());
mapView = (MapView) rootView.findViewById(R.id.mapcontainer);
mapView.onCreate(mapBundle);
map = mapView.getMap();
return rootView;
}
#Override
public void onResume(){
super.onResume();
mapView.onResume();
}
#Override
public void onPause(){
super.onPause();
mapView.onPause();
}
#Override
public void onDestroy(){
super.onDestroy();
mapView.onDestroy();
}
I found a solution from the discussion thread Bug: Black rectangle background on scroll that pointed me in the right direction. There seems to be some bugs in Google Play Services that can be resolved by setting the map to "Lite Mode". In my case it did the trick and the map is now working in the pagetransformer. From what I understand lite mode changes the map to a Bitmap Image. You can read more about it here Google Maps - Lite Mode. Lite mode has some limitation such as not being able to pan or zoom, but in my case it is not a requirement.
I updated my XML to this:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF">
<com.google.android.gms.maps.MapView
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="#+id/mapcontainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="false"
map:liteMode="true"/>
</FrameLayout>
You can also set this option in the code:
GoogleMapOptions options = new GoogleMapOptions().liteMode(true);
MapView mapView = MapView (context, options);

Reload a View on Orientation Change

In my Activity I have a View that "depends" from screen orientation. If it's in landscape mode, i use a layout under layout-large-hand, but if it's in portrait mode, I use the layouts under the layouts folder.
The Activity shows also a Map with some markers and informations.
In my AndroidManifest i have
android:configChanges="orientation|screenSize"
But the activity shows only the layout on portrait mode.
How can I fix this?
EDIT 3/12:
I have a layout like this:
<RelativeLayout 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" >
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment" />
<include
android:id="#+id/my_view"
layout="#layout/my_view"
android:visibility="gone" />
</RelativeLayout>
and i want that my_view changes the layout, but map remains with all markers, zoom level, position, ecc ecc...
my_view is visible when i click on a Button created dinamically in the activity.
EDIT 2:
Like SweetWisher ツ says, i was trying to setup a custom behaviour for the views. But when i rotate the device, the map disappear. This is part of my code in the activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initUI();
}
private void initUI() {
setContentView(R.layout.my_layout);
if (mp == null) {
mp = MapFragment.newInstance();
}
getFragmentManager().beginTransaction().replace(R.id.placeholder, mp).commit();
initUIStuff()
}
private void initUIStuff(){
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
initUI();
}
#Override
protected void onStart() {
super.onStart();
initGMap();
}
#Override
protected void onResume() {
super.onResume();
initGMap();
}
private void initGMap() {
if (mp != null {
//Initialize Map
}
}
If you use android:configChanges="orientation" in your Manifest you're preventing Android from doing default reset of view hierarchy on screen orientation change. You have to manually change your views in onConfigurationChanged method and by that I mean inflate your desired layout and replace your old layout with it. If you want to take advantage of Android automatic view hierarchy reset don't use android:configChanges="orientation".
Edit:
Use following code to add map fragment through XML:
<fragment
android:id="#+id/map"
android:name="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
You also don't need now 'onConfigurationChange' method so delete it.

Categories

Resources