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"/>
```
Related
I have a soundboard app, and I want to make a search bar so users can find the sounds by search. I have multiple tabs for the buttons. The buttons have different images, which are stored in an array. Each buton has textview below them, as a title. My questions is how to make a search bar so the users can find sounds from all of the 10 Tabs(around 300 sounds overall) at the same time? I have 10 Tabs so that means I have 30 arrays with different informations like the sound of the button, the image of the button, and the text for the textview below the buttons. Here are the codes:
single_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/button"
android:longClickable="true"
android:onClick="werbung"
android:padding="0dp"
android:text=""
android:textColor="#ffffff"
android:textSize="17dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/textview"
android:layout_width="0dp"
android:layout_height="42dp"
android:layout_below="#id/button"
android:layout_alignLeft="#id/button"
android:layout_centerInParent="true"
android:gravity="center"
android:text=""
android:textColor="#color/black"
android:textSize="17sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/button" />
</android.support.constraint.ConstraintLayout>
The arrays containing the texts for the textview, and the sounds and images for the buttons in Tab1.java(all of the tabs' code is the same, just with different arrays):
public String[] items = {
"text1", "text2", "text3"
};
public static int[] soundfiles ={
R.raw.sound1, R.raw.sound2, R.raw.sound3
};
public static int[] images ={
R.drawable.image1, R.drawable.image2, R.drawable.image3
};
The buttons with the text below them are created from the single_item.xml with this code(this is also in the Tab.java):
// CustomGrid Adapter
public class CustomGridAdapter extends BaseAdapter {
private Context context;
private String[] items;
LayoutInflater inflater;
public CustomGridAdapter(Context c, String[] items) {
this.context = c;
this.items = items;
inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return items.length;
}
#Override
public Object getItem(int position) {
return items[position];
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.single_item, null);
}
Button button = (Button) convertView.findViewById(R.id.button);
TextView textView = (TextView) convertView.findViewById(R.id.textview);
textView.setText(items[position]);
button.setBackgroundResource(images[position]);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (context instanceof MainActivity) {
((MainActivity) context).TabEightItemClicked(position);
}
}
});
return convertView;
}
}
Tab 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="match_parent"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:id="#+id/tab1">
<GridView
android:background="#ffffff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tabOneGridView"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:numColumns="auto_fit"
android:horizontalSpacing="0dp"
android:verticalSpacing="0dp"
android:columnWidth="155dp"
android:stretchMode="spacingWidthUniform"/>
</RelativeLayout>
Tab design: https://i.stack.imgur.com/NlC09.png
My ListView is goind to show the rank of users, usernames, and their score, smth like: 1. John 25
and I'd like to display the score just like it's shown on the example attached.
What you need to use is a CustomAdapter instead of the default adapter. Please refer to this other answer Custom Adapter for List View
Basically you create your own item layout: how you wish each item in the list will be displayed (it could be a TextView for the username and another TextView for the Score).
And then in the getView method of the Adapter set the value of each one.
You can achieve this using a custom list adapter and custom layout xml
Try this:-
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = findViewById(R.id.list_view);
listView.setAdapter(new NameRankAdapter(this));
}
}
NameRankAdapter.java
public class NameRankAdapter extends BaseAdapter {
private Context context;
public NameRankAdapter(Context context) {
this.context = context;
}
#Override
public int getCount() {
return 20;
}
#Override
public Object getItem(int i) {
return i;
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (view == null) {
view = LayoutInflater.from(context).inflate(R.layout.list_item, null);
}
TextView name = view.findViewById(R.id.name);
name.setText("Name " + i);
TextView rank = view.findViewById(R.id.rank);
rank.setText(String.valueOf(i));
return view;
}
}
activity_main.xml
<?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"
tools:context=".MainActivity">
<ListView
android:id="#+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:text="name"
android:id="#+id/name"
android:textSize="30sp"
android:textColor="#android:color/black"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="name"
android:textSize="25sp"
android:id="#+id/rank"
android:textColor="#android:color/black"/>
</FrameLayout>
I'm trying to figure out why an Android custom view which works when no background is set suddenly stops working when the background is set. It seems the background covers the items added to the view when it is set. I've simplified the view code to the bare minimum which reproduces the problem and to be able to post the code here. The custom view inherits from RelativeLayout and the code is as follow:
public class TestView extends RelativeLayout {
private LayoutInflater mInflater;
private ViewTreeObserver mViewTreeObserber;
private boolean mInitialized = false;
public TestView(Context ctx) {
super(ctx, null);
initialize(ctx, null, 0);
}
public TestView(Context ctx, AttributeSet attrs) {
super(ctx, attrs);
initialize(ctx, attrs, 0);
}
public TestView(Context ctx, AttributeSet attrs, int defStyle) {
super(ctx, attrs, defStyle);
initialize(ctx, attrs, defStyle);
}
private void initialize(Context ctx, AttributeSet attrs, int defStyle) {
mInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mViewTreeObserber = getViewTreeObserver();
mViewTreeObserber.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (!mInitialized) {
mInitialized = true;
drawItem();
}
}
});
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawItem();
}
private void drawItem() {
if (!mInitialized) return;
removeAllViews();
View item = mInflater.inflate(R.layout.testview_item, null);
TextView txt = (TextView)item.findViewById(R.id.test_view_item);
txt.setText("Test View Text");
txt.setTextColor(Color.BLACK);
txt.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12);
addView(item);
}
}
The item layout is simple:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal" >
<TextView
android:id="#+id/test_view_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:ellipsize="end"
android:maxLines="1" />
</LinearLayout>
And the sample app simply declares two instances of the custom view in XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin">
<TextView android:text="With Background set"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<com.machado.felipe.TestView
android:background="#android:color/holo_blue_light"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</com.machado.felipe.TestView>
<TextView android:text="WithOUT Background set"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<com.machado.felipe.TestView
android:layout_width="match_parent"
android:layout_height="wrap_content">
</com.machado.felipe.TestView>
</LinearLayout>
The result looks like the picture bellow:
This is driving me crazy! I'm not used to write custom views in android and this is someone else's code which I'm trying to fix! I don't even know if this is the way it should be done, since I'm inflating views and adding them to the RelativeLayout I don't think I should be adding them in the onDraw, but since the complete code is doing more complex stuff, as laying out the items in multiple rows with wrapping, it is possibly a valid approach... But, anyway, I can't figure out how to fix this!
I Want Something Like Shown In Image Below... As Item 3, Item 4 And Item 7 Has A Toggle Switch But Item 1, Item 2, Item 5, Item 6 Doesn't Have. Can Anyone Help Me To Make This Layout And Make Toggle Switch Work Too
I Want This (Made In Photoshop)
My Java File
import android.content.*;
import android.view.*;
import android.widget.*;
class CustomSettingsAdapter extends ArrayAdapter<String> {
String[] settingItems = {
"Themes",
"Entry Tune",
"Remember Last Location",
"About Us",
"Exit"
};
public CustomSettingsAdapter(Context context, String[] Items) {
super(context, R.layout.main_settings_listview, Items);
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
View customView = layoutInflater.inflate(R.layout.main_settings_listview, parent, false);
String itemName = getItem(position);
TextView textView =(TextView) customView.findViewById(R.id.itemName);
Switch mButton = (Switch) customView.findViewById(R.id.Switch);
if (position == 1 || position == 2) {
mButton.setVisibility(View.VISIBLE);
}
textView.setText(settingItems[position]);
return customView;
}
}
** XML **
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="6dp"
android:minHeight="48dp"
android:id="#+id/mainActivityListBackground"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Item Number"
android:id="#+id/itemName"
android:layout_marginLeft="5dp"
android:textSize="18sp"
android:layout_centerVertical="true"
/>
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/Switch"
android:visibility="invisible"
android:layout_alignParentRight="true"
/>
</RelativeLayout>
</RelativeLayout>
Use this code it help you.
item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/code"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_weight="1"
android:textSize="16dp" />
<Switch
android:id="#+id/toggleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:gravity="center"
android:text="Off"
android:visibility="invisible" />
</LinearLayout>
and use this adapter
public class PhoneAdapter extends BaseAdapter {
private Context context;
public PhoneAdapter(Context context) {
this.context = context;
}
#Override
public int getCount() {
return 7;
}
#Override
public Object getItem(int i) {
return i;
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(final int i, View convertView, ViewGroup viewGroup) {
convertView = View.inflate(context, R.layout.item, null);
TextView mCode = (TextView) convertView.findViewById(R.id.code);
Switch mButton = (Switch) convertView.findViewById(R.id.toggleButton);
mCode.setText("item"+i+1);
if (i == 2 || i == 3 || i == 6)
mButton.setVisibility(View.VISIBLE);
return convertView;
}}
and this is output:-
feel free to ask if you stuck anywhere in between.
EDIT:- getView() is use for identify which button is clicked so you don't want to care about it .In the getView() the i variable is used for identify which item is clicked.
Just set your OnchangeListner inside getView() and your problem solve.
You can use recycler view.You can do this by creating two xml for two different designs,and on basis of condition you can set view in layout inflater.Use these methods for extra views.
#Override
public int getViewTypeCount() {
return VIEW_TYPE_COUNT;
}
#Override
public int getItemViewType(int position) {
return position;
}
You can also refer to this link.
I am new to Android and I am currently developing an app that contains a listview with simple text. When the user clicks the text in the listview a sharing intent is triggered. I have used a custom adapter to set a different typeface to the text in my listview. The problem is when I run the app the listview is being seen but the content is invisible. But When I tap on the listview the sharing intent is triggered as it should be. I don't know what is causing it. I searched in Stack Overflow and google and tried some steps but it didn't work out for me. Please help me out. Thanks in advance.
Code:
Main.xml
<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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.proda.technologies.app.testapp"
android:background="#drawable/inspirationalbg">
<ImageButton
android:layout_width="130dp"
android:layout_height="40dp"
android:id="#+id/back_Button"
android:background="#drawable/backbutton"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<ListView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="#+id/list"
android:layout_below="#+id/back_Button"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
list_item.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">
<TextView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textColor="#ffffff"
android:id="#+id/instView"/>
</LinearLayout>
CustomAdapter.java
public class CustomAdapter extends ArrayAdapter<String>{
private final Context context;
private final String[] values;
public CustomAdapter(Context context, String[] values) {
super(context,R.layout.list_item,values);
this.context = context;
this.values = values;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context);
View rview = inflater.inflate(R.layout.list_item,null);
TextView txt = (TextView)rview.findViewById(R.id.instView);
AssetManager mgr = context.getAssets();
Typeface tf = Typeface.createFromAsset(mgr,"fonts/RalewayRegular.ttf");
txt.setTypeface(tf);
return rview;
}
}
Main.java
String[] phone = {"Nexus","Htc","Samsung","Oppo","Apple"};
Listview inslist;
inslist = (ListView)findViewById(R.id.list);
CustomAdapter adapter = new CustomAdapter(Main.this,phone);
inslist.setAdapter(adapter);
I am not getting any errors. I can see the listview with the lines seperating each content. But the actual content(text) is invisible. Please help me
Your ListViewItem contain a TextView but its value was not init.
Try to set value for textView in xml file or in java code.
Try one of below ways:
1. By XML file: list_item.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">
<TextView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:textColor="#ffffff"
android:id="#+id/instView"
android:text="This is text sample"/>
</LinearLayout>
2. by Java code: CustomAdapter.java
public class CustomAdapter extends ArrayAdapter<String>{
private final Context context;
private final String[] values;
public CustomAdapter(Context context, String[] values) {
super(context,R.layout.list_item,values);
this.context = context;
this.values = values;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context);
View rview = inflater.inflate(R.layout.list_item,null);
TextView txt = (TextView)rview.findViewById(R.id.instView);
txt.setText(values[position]);
AssetManager mgr = context.getAssets();
Typeface tf = Typeface.createFromAsset(mgr,"fonts/RalewayRegular.ttf");
txt.setTypeface(tf);
return rview;
}
}
I didn't see anywhere that you added text inside TextView.
Can you put the data to show in TextView view inside getView() method like :
txt.setText(values.get(position));