So I am trying to set a custom font (hello.ttf) which is already in the assets folder to a ListView. Below is my java and xml file.
faListFragment.java
public class faListFragment extends Fragment {
public faListFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_fa_list, container, false);
String[] faList = { "One",
"Two",
};
ListView listView = (ListView) view.findViewById(R.id.listFa);
ArrayAdapter<String> listviewAdapter = new ArrayAdapter<String>(
getActivity(),
android.R.layout.simple_list_item_1,
faList
);
listView.setAdapter(listviewAdapter);
// Inflate the layout for this fragment
return view;
}
}
and this is my fragment_fa_list.xml
<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="com.me.hello.faListFragment">
<!-- TODO: Update blank fragment layout -->
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/listFa" />
</FrameLayout>
I have tried several ways of adding the font, but cant quite seem to grasp how to go about it.
You have to create one layout xml in layout folder. In that layout xml you have to user custom textview with custom font.
For CustomTextView Link : Using custom font in android TextView using xml
ArrayAdapter<String> listviewAdapter = new ArrayAdapter<String>(
getActivity(),
R.layout.row_item, R.id.text ,
faList
);
listView.setAdapter(listviewAdapter);
Edit :
My CustomTextView Class
public class MyTextView extends TextView {
public MyTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MyTextView(Context context) {
super(context);
init();
}
private void init() {
if (!isInEditMode()) {
Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "fonts/Roboto-Regular.ttf");
setTypeface(tf);
}
}
}
row_item.xml
<RelativeLayout 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:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="15dp"
android:background="#00000000"
android:orientation="vertical">
<pakagename.MyTextView
android:id="#+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/title"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:text="CEO"
android:textColor="#000"
android:textSize="16dp" />
</RelativeLayout>
Related
I learning, how to create a android library and I create a simple onboarding Library. But I have a problem with my ViewPager from my custom module.
When I swipe in right and left, my seconds item is not display or first and second view is overlay.
I don't understand where the problem comes from
[![enter image description here][2]][2]
[![ ][3]][3]
Main class in my library:
public class OnBoardingView extends FrameLayout implements LifecycleObserver {
public OnBoardingView(#NonNull Context context) {
super(context, null);
this.initialize(context, null);
}
public OnBoardingView(#NonNull Context context, #NonNull AttributeSet attrs) {
super(context, attrs);
this.initialize(context, attrs);
}
private void initialize(#NonNull Context context, #Nullable AttributeSet attrs) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.onboarding_view_root, this);
List<String> list = new ArrayList<String>();
list.add("Hello world 1");
list.add("Hello world 2");
list.add("Hello world 3");
ViewPager viewPager = findViewById(R.id._screenPager);
OnBoardingAdapter<String> onBoardingAdapter = new OnBoardingAdapter<String>(context, list);
viewPager.setAdapter(onBoardingAdapter);
}
}
My adapter:
public class OnBoardingAdapter<T> extends PagerAdapter {
private Context context;
private List<T> onBoardingList;
public OnBoardingAdapter(Context context, List<T> list) {
this.context = context;
this.onBoardingList = list;
}
#Override
public int getCount() {
return this.onBoardingList.size();
}
#Override
public boolean isViewFromObject(#NonNull View view, #NonNull Object object) {
return view.getClass() == object.getClass();
}
#Override
public void destroyItem(#NonNull ViewGroup container, int position, #NonNull Object object) {
container.removeView((View) object);
}
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
View view = LayoutInflater.from(context).inflate(R.layout.onboarding_screen_view, null);
container.addView(view);
return view;
}
}
My XML file to content ViewPager :
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<androidx.viewpager.widget.ViewPager
android:id="#+id/_screenPager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
My Xml for each page:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="onboarding_screen_view" />
</LinearLayout>
And in main main_activity file I call this to display my module:
<com.domaine.onboarding.OnBoardingView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
Try to return view instead of container
If you want to achieve this easily try to use viewpager2, you can use adapter that similar with recyclerview adapter
https://developer.android.com/training/animation/vp2-migration
I have surveyed in other sites and got different responses about how I can solve my problem. In fact the problem is that I am trying to make a responsive gridView layout to display 25 textviews with numbers. I had hard time in constructing it the way I want but here is what I got:
<LinearLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="10"
android:layout_gravity="center"
android:gravity="center"
tools:context="com.example.hristodraganov.bingo.MainActivity"
tools:showIn="#layout/activity_main">
<RelativeLayout
android:id="#+id/relLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="4">
</RelativeLayout>
<GridView
android:paddingTop="8dp"
android:id="#+id/gridview"
android:background="#000"
android:layout_width="match_parent"
android:layout_weight="6"
android:layout_height="0dp"
android:gravity="center"
android:columnWidth="70dp"
android:numColumns="5"
android:verticalSpacing="10dp"
android:horizontalSpacing="1dp"
android:stretchMode="spacingWidth"
/>
This is the layout that is used on the MainActivity. I inflate it with textview item with this code:
<?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:background="#d3d3d3"
android:gravity="center">
<com.example.****.****.SquareView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/cell"
android:textColor="#D0583B"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="30sp">
</com.example.****.****.SquareView>
There is the extension of the BaseAdapter class that is used to inflate the grid with the textviews:
public class GridAdapter extends BaseAdapter {
private final Context mContext;
private String[] numbers;
public GridAdapter(Context context, String[] numbers) {
this.mContext = context;
this.numbers = numbers;
}
#Override
public int getCount() {
return numbers.length;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater)
mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
if (convertView == null) {
gridView = new View(mContext);
gridView = inflater.inflate(R.layout.textview_layout, null);
TextView textView = (TextView) gridView.findViewById(R.id.cell);
textView.setText(numbers[position]);
} else {
gridView = (View) convertView;
}
return gridView;
}
}
Also, I am forcing the textView to be squared in this SquareView class:
public class SquareView extends android.support.v7.widget.AppCompatTextView {
public SquareView(Context context) {
super(context);
}
public SquareView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}}
The layout is doing fine by now, here is an image of the size I used to construct it Nexus 5X. It looks good but when I change to 4" -Nexus S the whole last row is somewhere below the screen. Also this happens to 5"-Nexus 5 where the last row is slightly visible. Above 5.2" to 6.0" the layout fits perfectly. So my question is what should I do in this scenario to make the layout fit for small-sized screens without making a duplicate layout for them. (Note: I was told that the BaseAdapter implementation would fix the responsiveness of the layout). Any ideas what could I do? (Sorry for the long texts.)
Because there are a lot of different Android devices out there your best choice would be to encapsulate your layout in a ScrollView.
Another option is to get rid of the weights and let the top RelativeLayout grow/shrink after the GridView has taken all the space it needs. This still might not work on smaller screens or in landscape.
```
<RelativeLayout
android:id="#+id/relLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</RelativeLayout>
<GridView
android:paddingTop="8dp"
android:id="#+id/gridview"
android:background="#000"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:columnWidth="70dp"
android:numColumns="5"
android:verticalSpacing="10dp"
android:horizontalSpacing="1dp"
android:stretchMode="spacingWidth"/>
```
i create a ConstrantLayout class
public class AboutView extends ConstraintLayout {
TextView about_txt;
TextView dr_txt;
public AboutView(Context context) {
super( context );
init();
}
public AboutView(Context context, AttributeSet attrs, int defStyleAttr) {
super( context, attrs, defStyleAttr );
init();
}
private void init() {
LayoutInflater inflater = LayoutInflater.from( getContext() );
inflater.inflate( R.layout.about_layout,this );
about_txt = (TextView) findViewById(R.id.about_txt);
dr_txt = (TextView) findViewById(R.id.dr_txt);
}
}
Layout about_layout.XML file to inflate into class
Create layout how you want your custom view to look like. There is nothing complicated about it.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayoutxmlns: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"
xmlns:tools="http://schemas.android.com/tools">
<TextView
android:id="#+id/about_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
app:layout_constraintStart_toStartOf="parent"
tools:text="About" />
<TextView
android:id="#+id/dr_txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="parent"
tools:text="Text" />
</android.support.constraint.ConstraintLayout>
This way you can set constraints and edit the layout with editor.
AFTER you are done with editting I would recommend changing the root view ConstraintLayout to merge.
By merging you won't have extra layout inside the custom view. Be careful - merge attributes are ignored.
I am trying to embed a RecyclerView within the body of a custom view (a RefreshableList).
This is my project's structure: it contains 2 modules, app & rlist.
the rlist module holds the custom view (RefreshableList) in which I want to embed a RecyclerView.
RefreshableList.java (The custom view)
public class RefreshableList extends RelativeLayout {
private RecyclerView mRecyclerView;
private Context mContext;
private MyAdapter mAdapter;
public RefreshableList(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
Log.i("ADAPTER", "RefreshableList is initializing views...");
setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
LayoutInflater inflater = (LayoutInflater) context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.refreshable_list, null);
findViewsById(view);
setupRecyclerView();
}
private void findViewsById(View view) {
mRecyclerView = (RecyclerView) view.findViewById(R.id.dataRecyclerView);
Log.i("ADAPTER", "RecyclerView has been initialized.");
}
private void setupRecyclerView() {
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(mContext));
Log.i("ADAPTER", "RecyclerView has been setup.");
}
public void setAdapter(MyAdapter adapter) {
mAdapter = adapter;
mRecyclerView.setAdapter(mAdapter);
Log.i("ADAPTER", "Adapter has been set." + mAdapter.getItemCount());
}
}
MyAdapter.java (The RecyclerView's adapter)
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
protected Context mContext;
protected List<String> mItems;
public MyAdapter(Context context, List<String> items) {
mContext = context;
mItems = new ArrayList<>(items);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_row, parent, false);
Log.i("ADAPTER", "Creating row...");
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.label.setText(mItems.get(position));
}
#Override
public int getItemCount() {
return mItems.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView label;
public ViewHolder(View itemView) {
super(itemView);
label = (TextView) itemView.findViewById(R.id.label);
}
}
}
item_row.xml: (the XML layout of the RecyclerView's elements)
<?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="60dp">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="New Text"
android:id="#+id/label"
android:gravity="left|center_vertical"
android:padding="8dp"
android:background="#ff0000"/>
</LinearLayout>
refreshable_list.xml: (The XML layout of the RefreshableList custom view)
<?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">
<android.support.v7.widget.RecyclerView
android:id="#+id/dataRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
All this code belongs to the rlist module. In order to test it out, I added a MainActivity to the app module where I embed a RefreshableList:
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Bind(R.id.list)
RefreshableList mRefreshableList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
mRefreshableList.setAdapter(new MyAdapter(
this, Arrays.asList("Java", "Android", "Python", "Kivy")));
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.zouag.refreshablelist.MainActivity"
android:background="#00ff00">
<com.zouag.rlist.RefreshableList
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffff00"/>
</RelativeLayout>
After running the application, I can't see any of the RecyclerView's elements: (even though the RecyclerView is clearly visible, marked with yellow)
What am I missing here ?
Not your recyclerview is visible, your relativelayout is.
You don't attach the inflated layout to your viewgroup.
The call :
View view = inflater.inflate(R.layout.refreshable_list, null);
just inflates the layout but dosen't attach it to a view.
If u wanna stick with this you need to attach the view after inflating by:
this.addView(view)
Or just call:
View view = inflater.inflate(R.layout.refreshable_list, this,true);
which attaches the inflated layout to the root view.
I have a custom widget thats extends Linear layout.
It just block of text with litle.
Here is xml of widget:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:background="#drawable/actionbar_background"
android:layout_height="35dp"
android:paddingLeft="15dp"
android:gravity="center_vertical">
<TextView
android:id="#+id/title"
android:layout_height="35dp"
android:textColor="#color/white"
android:layout_width="match_parent"
android:textSize="18dp"
android:clickable="true"
android:gravity="center_vertical" />
</LinearLayout>
<TextView
android:id="#+id/ingreds"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="Some text"
android:paddingLeft="15dp" />
</LinearLayout>
If I creating onClickListener for that custom widget somewhere in Activity - it reacts only if I click on last TextView in that layout. But I need to set onClickListener for horizontal LinearLayout which contains "title" textView, or directly on title TextView.
Important: I want to set these listeners OUTSIDE the custom widget class.
I think that I need to override setOnclickListener method in my custom class or something like that, but I'm not sure how it can be done.
Here is the class of custom widget:
public class MyTextBlock extends LinearLayout {
private TextView title;
private TextView ingreds;
public MyTextBlock(Context context) {
this(context, null);
}
public MyTextBlock(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.my_text_block, this, true);
title = (TextView) findViewById(R.id.title);
ingreds = (TextView) findViewById(R.id.ingreds);
}
public void setText(String text) {
ingreds.setText(text);
}
public void setTitle(String titleText) {
title.setText(titleText);
}
}
Thanks for answering.
Just implement the OnClickListener to this view class and set textview.setOnClickLister(this);
now handle the click event under the onClick(View v) method.
MyTextBlock textviewCustom = ....
textviewCustom.setonclickListner(MainClass.this);
public class MyTextBlock extends LinearLayout {
private TextView title;
private TextView ingreds;
public MyTextBlock(Context context) {
this(context, null);
}
public MyTextBlock(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.my_text_block, this, true);
title = (TextView) findViewById(R.id.title);
ingreds = (TextView) findViewById(R.id.ingreds);
}
public void setonclickListner(OnclickListner listner)
{
title.setonclicklistner(listner);
ingreds.setonclicklistner(listner);
}
public void setText(String text) {
ingreds.setText(text);
}
public void setTitle(String titleText) {
title.setText(titleText);
}
}