I have a strange issue that I have a workaround for but wondered if anyone could shed some light on why this is happening and a more elegant fix maybe?
I have a ViewPager with a series of Fragments. The Fragments use their own layout and when an ImageView is added to the layout the ImageView isnt rendered at runtime.
If I explicitly set the imageDrawable for the ImageView inside the Fragment's onCreateView method (even though the image is the same image as being referenced in the layout xml then the image shows fine.
Here is my Fragment xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/baseRelLayout"
android:background="#color/colorPrimary">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="#drawable/flamerite_remote_6"
android:layout_marginStart="36dp"
android:id="#+id/remote6ButtonImage"
android:layout_alignParentBottom="false"
android:layout_alignStart="#+id/textView3"
android:scaleType="fitXY"
android:background="#color/colorPrimary"
android:layout_alignBottom="#+id/remote9ButtonImage" />
</RelativeLayout>
And here is where I am re-setting the image drawable inside onCreateView
public class WizardFragment extends Fragment {
public static final String STEP_NUMBER = "STEP_NUMBER";
public static final WizardFragment newInstance(String message){
WizardFragment f = new WizardFragment();
Bundle bdl = new Bundle(1);
bdl.putString(STEP_NUMBER,message);
f.setArguments(bdl);
return f;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.wizard_fragment_step_1, container, false);
ImageView remoteImage9Button = (ImageView)v.findViewById(R.id.remote9ButtonImage);
remoteImage9Button.setImageDrawable(ResourcesCompat.getDrawable(getResources(),R.drawable.flamerite_remote_9, null)); //THIS IS THE LINE THAT MAKES THE IMAGE WORK AGAIN
return v;
}
}
I can of course keep this re-set of the imageDrawable in but think it is strange that the image shoudlnt be showing when only set in the xml layout
Any thoughts greatly appreciated!!
I do not know the reason, but in my case the same issue was resolved when I changed
image src definition from
app:srcCompat="#drawable/logo"
to
android:src="#drawable/logo"
Just add android:src="#drawable/logo" instead of app:srcCompat
Related
I have a fragment class which uses Recycleview to show list of Text and Image.
How can I access Recycleview row items and set an custom text to any Textview or Hide the Desired Textview from fragment class.
This is my layout
<?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"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:paddingBottom="4dp"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:paddingTop="4dp">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none" />
<include
android:id="#+id/include_tag"
layout="#layout/row_item"/>
</FrameLayout>
and My row item layout is
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res /android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent">
<TextView
android:id="#+id/flower_Name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textStyle="bold"
android:maxLines="1"
android:layout_centerInParent="true"
android:gravity="center_vertical|center_horizontal"
android:textAlignment="center"
android:textColor="#E91E63"
android:fontFamily="sans-serif-condensed"
android:text="Sagar Rawal"/>
<TextView
android:layout_marginTop="8dp"
android:id="#+id/flower_details"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textStyle="bold"
android:maxLines="3"
android:textColor="#673AB7"
android:text="This Text need to Be Change "/>
</RelativeLayout>
and my Fragment class i s
public View onCreateView(final LayoutInflater inflater, #Nullable final ViewGroup container, #Nullable Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.activity_main, container, false);
View test1View = view.findViewById(R.id.include_tag);
mhideText = (TextView) test1View.findViewById(R.id.flower_details);
mhideText.setVisibility(View.INVISIBLE);
return view;
But it doesn't work. and Textview is still Visible.
Please help. Thanks in advance.
You must have a custom ViewHolder which should extends RecyclerView.ViewHolder. In your ViewHolder you can link row item and you can access all views from your row layout.
Your custom ViewHolder looks like:
public static class MyViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView textView;
public MyViewHolder(TextView v) {
super(v);
textView = v;
//Note: To set custom text
textView.setText("My custom text");
//Note: To hide TextView remove comment from below line
//textView.setVisibility(View.GONE);
}
}
Above code shows sample ViewHolder as MyViewHolder where you can access your views.
If you are passing parent Layout to MyViewHolder instead of passing TextView then you can find child views using v.findViewById(R.id.xxx)
Your adapter should contain similar code as below:
#Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
TextView v = (TextView) LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_text_view, parent, false);
...
MyViewHolder vh = new MyViewHolder(v);
return vh;
}
In above code snippet, creating instance of MyViewHolder by passing the view TextView. You can pass parent layout in your case its RelativeLayout from your row layout.
Use this ViewHolder to take any actions on views like set custom text to TextView or you can hide TextView as per your requirements.
To refer full example you can follow the android documentation or click here.
To achieve communication between ViewHolder and fragment you can use Interface.
Thank you!
Try doing this :
rowview = inflater.inflate(R.layout.row_item, container, false);
mhideText = (TextView)rowview.findViewById(R.id.flower_details);
mhideText.setVisibility(View.INVISIBLE);
Alright so I have a fragment and I'd like to include, within its' xml file another layout which is programmatically inflated
Fragment:
public class zGoal_Fragment extends Fragment{
private LinearLayout todayView;
private View view;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.main_goal_view, container, false);
todayView = (LinearLayout)view.findViewById(R.id.todayView);
return view;
}
}
xml's file for fragment:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="#+id/todayView"
>
</LinearLayout>
and xml layout I want included within the above xml programmatically:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/goalEditLayout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#color/test_color_two"
>
</LinearLayout>
I've tried a couple different methods all of which led to " on a null object reference" errors...
plz help :))
I suppose the solution which you are looking for are Android ViewStubs. These are dynamically inflated layouts.
For more information you could refer these :
How to use View Stub in android
https://developer.android.com/reference/android/view/ViewStub.html
However, if you don't wish to inflate one layout inside another during runtime, you could try this the include tag:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="#+id/todayView">
<include layout="#layout/your_layout_file_name"/>
</LinearLayout>
Have you tried something like this:
LinearLayout child = getLayoutInflater().inflate(R.layout.goalEditLayout, null);
todayView.addView(child);
Edit:
Inside onCreateView:
LinearLayout inflatedLayout = (LinearLayout) inflater.inflate(R.layout.goalEditLayout, todayView, true);
So I think I have gone through all the answers here on stackoverflow for this problem. However, noone of them have helped.
I am currently working with the camera2 example by Google trying to add an imageview "imageOverlay" that covers the whole screen. However, imageview is always null when trying to retrieve it. Any idea what I am missing?
Edit:
What has been tried:
Moving the ImageView in the camera_fragment.xml into the FrameLayout so that I can retrieve it just like the Button. This seemed like the best idea to make it an overlay.
Using getView()
Using getActivity()
Cleaning and rebuilding.
Using View view = inflater.inflate(R.layout.camera_fragment, null);
Camera_Activity xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000"
tools:context="com.irg.hig.imageregistrationgame.CameraActivity"
/>
camera_fragment.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.irg.hig.imageregistrationgame.CameraTextureView
android:id="#+id/texture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true" />
<ImageView
android:id="#+id/imageOverlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0.5" />
<FrameLayout
android:id="#+id/control"
android:layout_width="match_parent"
android:layout_height="112dp"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:background="#color/control_background">
<Button
android:id="#+id/picture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="#string/picture" />
<ImageButton
android:id="#+id/info"
android:contentDescription="#string/description_info"
style="#android:style/Widget.Material.Light.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|right"
android:padding="20dp" />
</FrameLayout>
</RelativeLayout>
CameraFragment.java:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.camera_fragment , container, false);
imageView = (ImageView) view.findViewById(R.id.imageOverlay);
return view;
}
#Override
public void onViewCreated(final View view, Bundle savedInstanceState) {
view.findViewById(R.id.picture).setOnClickListener(this);
view.findViewById(R.id.info).setOnClickListener(this);
mTextureView = (CameraTextureView) view.findViewById(R.id.texture);
//imageView = (ImageView) view.findViewById(R.id.imageOverlay);
}
The problem was that there was a second xml file in layout-v21 that was used and not the one in the Layout folder that I was trying to change.
Thanks to everyone that tried to help, it was appreciated immensely.
Try this.
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.your_layout, null);
Try to replace : View view = inflater.inflate(R.layout.camera_fragment , container, false);
by View view = inflater.inflate(R.layout.camera_fragment, null);
for this project, I have tabs that have to display something under them and i'm using view pager but for some reason, the fragment layout isn't showing up on screen. I get a blank screen but there is no error or anything. I have been googling and searching for hours now and even started a new project just to make sure it was not a build error but still no luck in finding a solution to my problem.
I have done examples like this many times and used the exact same steps but for some reason, it just isn't working this time. Any help would be greatly appreciated
Here is my mainActivity class
public class MainActivity extends ActionBarActivity {
Toolbar toolbar;
ViewPager myViewPager;
SlidingTabLayout mySlidingTabs;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
myViewPager = (ViewPager) findViewById(R.id.viewPager);
myViewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager(), this));
mySlidingTabs = (SlidingTabLayout) findViewById(R.id.sliding_tabs);
mySlidingTabs.setViewPager(myViewPager);
}
}
Here is my custom adapter class
public class MyPagerAdapter extends FragmentPagerAdapter {
private Context context;
private String[] tabNames = {"Beverages", "Deli & Bakery", "Fresh Produce", "Health & Beauty", "Meat & Seafood", "Natural Foods", "Pet Care"};
public MyPagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.context = context;
}
#Override
public Fragment getItem(int position) {
if (position == 0) {
return new Beverages();
}
else if (position == 1) {
return new DeliBakery();
}
return null;
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
return tabNames[position];
}
}
Here is my main activty.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar_layout"
android:layout_height="wrap_content"
android:layout_width="match_parent" />
<!-- The Sliding tab -->
<bello.myapplication.SlidingTabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/sliding_tabs"/>
<!-- The pager that allows us to swipe between fragments -->
<android.support.v4.view.ViewPager
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
android:background="#android:color/white" />
</LinearLayout>
and here is one of my tab's xml file
<?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="match_parent">
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tab fragment 1"
android:textSize="50dp"
android:padding="5dp" />
</RelativeLayout>
Here is one of my fragment classes
public class Beverages extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.beverages_tab, container, false);
return view;
}
}
When something strange like this happens, try to use Log.i("title", "message") to track if every class/methods are being called.
In your case, it seens that your viewpager isn't in the screen.
If I understood your code, your <include> tag is including the second xml code you posted right?
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tab fragment 1"
android:textSize="50dp"
android:padding="5dp" />
</RelativeLayout>
It looks like your layout_height="match_parent" is filling all the space on your screen, giving no space to your ViewPager being inflated by the system, try to change it to layout_height="wrap_content and you should be done.
If not, try to change the background of your ViewPager to check if it is on the screen and is not being hided by something else.
Figured out the problem. The viewpager background color and the background color of the tabs where the same so it made it look like there was a black activity. So for anyone else out there with the same problem, try changing either the text color of your tabs.xml or change the background of your viewpager
Introduction
I want to have different fragments depending on the user's choice from the navigation drawer. For every item in the navigation drawer is a different site that should called. I want to achieve this by fragments.
The main fragment will get displayed first by doing the following in the onCreate-method
if ( savedInstanceState == null ) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment fragment = MainFragment.passList(hashMap);
ft.replace(R.id.content_frame, new MainFragment());
ft.commit();
}
As you can see I'm passing data (a hashmap) to a method of the fragment which works perfectly. The data then gets put into string arrays. This works and the data can also be used in the onCreate-method of the fragment.
This is the xml of the main activity
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ListView
android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/darker_gray"
android:dividerHeight="0.1dp" />
</android.support.v4.widget.DrawerLayout>
And this is the XML of the main fragment
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainRelativeLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/activatedBackgroundIndicator"
android:gravity="center_vertical"
android:paddingRight="10dp"
>
<ScrollView
android:id="#+id/mainScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.03" >
<LinearLayout
android:id="#+id/mainListView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
</ScrollView>
</RelativeLayout>
What I want to achieve now is to display data in the scroll view. But the question I have, is how do I populate that and how do I initliaze it?
Normally I would go and just create them like that - because findViewById doesn't work in a Fragment (Have to write the method by my own)
ScrollView sv = new ScrollView(getActivity());
LinearLayout ll = new LinearLayout ( getActivity() );
sv.addView(ll);
ll.addView(SAMPLETEXTVIEW);
View mainView = inflater
.inflate(R.layout.main_fragment, container, false);
return mainView;
but that just leaves me with a blank screen and no actual text added. How can I achieve this? The data is there - I know that, because it gets printed out with System.out.println - I just need a way to display it. Thx in advance!
EDIT
When I do it like that
View rootView = inflater.inflate(R.layout.main_fragment, container, false);
ScrollView sv = (ScrollView) rootView.findViewById(R.id.mainScrollView);
LinearLayout ll = (LinearLayout) rootView.findViewById(R.id.mainListView);
sv.addView(ll);
I get just an IllegalStateException that ScrollView can only host one direct child... But I don't get it. The linearlayout is the only thing that is the direct child. Why is there a problem?
Here is the complete onCreateView-method
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.main_fragment, container, false);
ScrollView sv = (ScrollView) rootView.findViewById(R.id.mainScrollView);
LinearLayout ll = (LinearLayout) rootView.findViewById(R.id.mainListView);
sv.addView(ll);
source = new TextView[hashMapSize];
for (int i = 0; i < hashMapSize; i++) {
source[i] = new TextView(getActivity());
source [i].setText( "Source: " + sourceArr [i] );
ll.addView(source[i]
}
return rootView;
}
The reason you get the IllegalStateException is because you inflate your R.layout.main_fragment which already contains your ScrollView that already has one direct child (declared in you layout xml).
You shouldn't add in code with sv.addView(ll) it's already there. All you need to do is get the references as you already do with findViewById.
Remove the sv.addView(ll); and you should be fine.