Custom Attributes in Android Fragments

Custom XML attributes without custom View in Fragment

I have finally done this :)

You have to create a new LayoutInflater.Factory as I did on the OP but since the Factory is used for all the inflated layout View, and you have to return null on your Factory.onCreateView (to let Android handle the inflation) you must cache your custom XML attibutes somewhere

So here the solution :

  • Your layout XML View must have and android:id

  • Create the class which will keep your custom attributes :

    public class AttributeParser {

private AttributeParserFactory mFactory;
private Map<Integer, HashMap<Integer, String>> mAttributeList;

private class AttributeParserFactory implements LayoutInflater.Factory{
@Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
String id = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "id");

if(id != null){
// String with the reference character "@", so we strip it to keep only the reference
id = id.replace("@", "");

TypedArray libraryStyledAttributeList = context.obtainStyledAttributes(attrs, R.styleable.NewsHubLibrary);
HashMap<Integer, String> libraryViewAttribute = new HashMap<Integer, String>();
int i = 0;

for(int attribute : R.styleable.NewsHubLibrary){
String attributeValue = libraryStyledAttributeList.getString(i);

if(attributeValue != null)
libraryViewAttribute.put(attribute, attributeValue);

i++;
}

if(!libraryViewAttribute.isEmpty())
mAttributeList.put(Integer.valueOf(id), libraryViewAttribute);

libraryStyledAttributeList.recycle();
}

return null;
}

}

public AttributeParser(){
mAttributeList = new HashMap<Integer, HashMap<Integer, String>>();
mFactory = new AttributeParserFactory();
}

public void clear() {
mAttributeList.clear();
}

public LayoutInflater getLayoutInflater(LayoutInflater inflater) {
clear();
LayoutInflater layoutInflater = inflater.cloneInContext(inflater.getContext());
layoutInflater.setFactory(mFactory);

return layoutInflater;
}

public void setFactory(LayoutInflater inflater){
inflater.cloneInContext(inflater.getContext()).setFactory(mFactory);
}

public void setViewAttribute(Activity activity) {
for(Entry<Integer, HashMap<Integer, String>> attribute : mAttributeList.entrySet())
if(activity.findViewById((Integer) attribute.getKey()) != null)
activity.findViewById((Integer) attribute.getKey()).setTag(attribute.getValue());

}

public void setViewAttribute(View view) {
for(Entry<Integer, HashMap<Integer, String>> attribute : mAttributeList.entrySet())
if(view.findViewById((Integer) attribute.getKey()) != null)
view.findViewById((Integer) attribute.getKey()).setTag(attribute.getValue());
}

public Map<Integer, HashMap<Integer, String>> getAttributeList() {
return mAttributeList;
}

public void setAttributeList(Map<Integer, HashMap<Integer, String>> attributeList) {
this.mAttributeList = attributeList;
}
}
  • Your custom attributes will be stored in each View tag when you use the AttributeParser :


    LayoutInflater layoutInflater = mAttributeParser.getLayoutInflater(inflater);
View view = layoutInflater.inflate(R.layout.jedi, null);
mAttributeParser.setViewAttribute(view);

Android - Fragment - Set attributes for fragment

try:

Bundle bundle=new Bundle();
bundle.putString("message", "From Activity");
fragment.setArguments(bundle);

from your calling activity

How to send list from a fragment to a custom view class in android?

You need to Invalidate the View Since your data is dynamic you can do all the in it stuff after setting the data. Below is an example which should work.

public class BannerSliderView extends FrameLayout {
private ViewPager viewPager;
private PageIndicatorView pageIndicatorView;
private List<Banner> bannersList;
private BannerViewPagerAdapter bannerViewPagerAdapter;
public BannerSliderView(@NonNull Context context) {
this(context, null);
}

public BannerSliderView(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, -1);
}

public BannerSliderView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}

private void init() {
View view = View.inflate(getContext(), R.layout.banner_slider_layout, null);
viewPager = view.findViewById(R.id.viewPager);
viewPager.setPageMargin(valueInPixels);
pageIndicatorView = view.findViewById(R.id.pager_indicator);
addView(view);
}

public void setBannersList(List<Banner> bannersList) {
this.bannersList = bannersList;
bannerViewPagerAdapter = new
BannerViewPagerAdapter(getContext(), bannersList);
viewPager.setAdapter(bannerViewPagerAdapter);
pageIndicatorView.setViewPager(viewPager);
}
}

With this approach bannerViewPagerAdapter will be null before any call to setBannersList . Or you can just set the adapter inside #init and just update data in setBannersList.

Android Custom Map Fragment Attributes

Because below code returns null

mapFragment = ((SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.fragment));

Use should use SupportMapFragment in xml too

  <fragment
android:layout_width="wrap_content"
android:layout_height="250dp"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:id="@+id/fragment"
android:layout_below="@+id/imageView3"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginTop="31dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />

Pass Attributes before CustomView inflation in Fragment based on holder Activity

onInflated in fragment lifecycle which is called before onAttach() can solve this issue.



Related Topics



Leave a reply



Submit