I'm currently writing an app and it's been suggested I try a square list with tiles instead of a standard list. I've included an example mock up underneath of what it could look like. I'm relatively new to android and can't quite get my head around how I could do it.
Any help is much appreciated. Thanks!
You would have to use a 2 column GridView.
Assuming you have some model for an Alarm.
public class Alarm {
private String title;
private String time;
private int color;
public Alarm(String title, String time, int color) {
this.title = title;
this.time = time;
this.color = color;
}
}
You will have to create a custom layout to be used in the GridView
<?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"
android:background="#000">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="22sp"
android:id="#+id/title"
android:textColor="#FFFFFF"
android:text="title"
android:layout_centerHorizontal="true"
android:layout_margin="20dp"
/>
<TextView android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textSize="18sp"
android:id="#+id/time"
android:layout_below="#id/title"
android:text="time"
android:layout_centerHorizontal="true"
android:layout_margin="20dp"
android:textColor="#FFFFFF"/>
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/time"
android:layout_centerHorizontal="true"
android:src="#android:drawable/ic_media_play"/>
</RelativeLayout>
And create an adapter, just like you would when using a listview
public class AlarmGridAdapter extends BaseAdapter {
private Context context;
private List<Alarm> alarms;
public AlarmGridAdapter(Context context, List<Alarm> alarms) {
this.context = context;
this.alarms = alarms;
}
#Override
public int getCount() {
return alarms.size();
}
#Override
public Object getItem(int position) {
return alarms.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View root = layoutInflater.inflate(R.layout.grid_item, parent, false);
Alarm alarm = alarms.get(position);
TextView titleText = (TextView) root.findViewById(R.id.title);
TextView timeText = (TextView) root.findViewById(R.id.time);
root.setBackgroundColor(alarm.getColor());
titleText.setText(alarm.getTitle());
timeText.setText(alarm.getTime());
return root;
}
}
The activity simply contains a grid view, with the number of columns 2 and vertical/horizontal spacing 0
<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=".MainActivity">
<GridView
android:id="#+id/grid"
android:layout_width="match_parent"
android:numColumns="2"
android:horizontalSpacing="0dp"
android:verticalSpacing="0sp"
android:layout_height="match_parent" />
</RelativeLayout>
And finally, in the activity(or fragment):
private GridView gridView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridView = (GridView) findViewById(R.id.grid);
Alarm alarm1 = new Alarm("Alarm 1", "10:04:16", Color.parseColor("#39C6F4"));
Alarm alarm2 = new Alarm("Alarm 2", "10:04:16", Color.parseColor("#A33293"));
Alarm alarm3 = new Alarm("Alarm 3", "10:04:16", Color.parseColor("#F79922"));
Alarm alarm4 = new Alarm("Alarm 4", "10:04:16", Color.parseColor("#84C542"));
AlarmGridAdapter adapter = new AlarmGridAdapter(this, Arrays.asList(alarm1, alarm2, alarm3, alarm4));
gridView.setAdapter(adapter);
}
Result:
Related
I have a problem with spinner it do not let me select one item. I tried a lot of things and that still not working.
The picture shows that the spinner is in blank when the activity load
When I clicked the arrow it shows the items
but when I choose one, nothing happends.
<?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"
tools:context=".Activities.Inspeccion.DatosGeneralesActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/scrollView"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="15dp"
>
<TextView
android:id="#+id/tvSubestacionTitulo"
android:layout_below="#+id/imgLogo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/strSubestacion"
android:textSize="18sp"
android:textColor="#color/colorPrimaryDark"
android:textStyle="bold"
/>
<TextView
android:id="#+id/tvSubestacionDato"
android:layout_below="#+id/tvSubestacionTitulo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp"
android:text="Prueba"
/>
<Spinner
android:id="#+id/spinnerSubEstacion"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/tvSubestacionDato"
>
</Spinner>
</RelativeLayout>
</ScrollView>
</RelativeLayout>
This is the Layout of the activity.
<?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="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/tvNumeroOpcion"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="15dp"
android:layout_marginTop="5dp"
android:text="1"
android:textColor="#color/black"
android:textSize="14sp" />
<TextView
android:id="#+id/tvDescriptionOption"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="15dp"
android:layout_marginTop="5dp"
android:text="Guatemala"
android:textColor="#color/black"
android:textSize="14sp" />
</LinearLayout>
That is the custom layout for the spinner
Public class ComboAdapter extends BaseAdapter{
private List<Combo> combos;
private Activity activity;
private LayoutInflater inflater;
public ComboAdapter(List<Combo> combos, Activity activity) {
this.combos = combos;
this.inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return combos.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (convertView == null){
view = inflater.inflate(R.layout.combo_list_item, null);
TextView tvId = (TextView) view.findViewById(R.id.tvNumeroOpcion);
TextView tvDescripcion = (TextView) view.findViewById(R.id.tvDescriptionOption);
tvId.setText(combos.get(position).getId());
tvDescripcion.setText(combos.get(position).getDescripcion());
}
return view;
}
#Override
public View getDropDownView(int position, View convertView,
ViewGroup parent) {
return getView(position, convertView,parent);
}
}
That is my Adapter
And below is my activity.
public class DatosGeneralesActivity extends AppCompatActivity {
private TextView tvSubestacionDato;
private List<Combo> listaCombo;
private Spinner spinnerSubestacion;
private ArrayAdapter<Combo> adapterSubestacion;
String seleccion;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_datos_generales);
//Inicializando textos
tvSubestacionDato = (TextView) findViewById(R.id.tvSubestacionDato);
//Inicializanco listas
listaCombo = new ArrayList<>();
//Inivializando spinners
spinnerSubestacion = (Spinner) findViewById(R.id.spinnerSubEstacion);
AppService service = API.getCombos().create(AppService.class);
Call<List<Combo>> subestacionCall = service.getSubestacion();
subestacionCall.enqueue(new Callback<List<Combo>>() {
#Override
public void onResponse(Call<List<Combo>> call, Response<List<Combo>> response) {
listaCombo.clear();
listaCombo.addAll(response.body());
}
#Override
public void onFailure(Call<List<Combo>> call, Throwable t) {
}
});
//final ComboAdapter adapter = new ComboAdapter(listaCombo, DatosGeneralesActivity.this);
final ArrayAdapter<Combo> adapter = new ArrayAdapter<Combo>(this, R.layout.support_simple_spinner_dropdown_item, listaCombo);
spinnerSubestacion.setAdapter(adapter);
spinnerSubestacion.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
adapter.notifyDataSetChanged();
Toast.makeText(DatosGeneralesActivity.this, ""+position, Toast.LENGTH_SHORT).show();
tvSubestacionDato.setText(listaCombo.get(position).getDescripcion());
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
Try this changes:
Call adapter like:
ComboAdapter adapter = new ComboAdapter(DatosGeneralesActivity.this,
R.layout.combo_list_item, R.id.tvDescriptionOption, listaCombo);
now in adapter class:
public ComboAdapter(Activity context,int resouceId, int textviewId, List<Combo> list){
super(context,resouceId,textviewId, list);
this.combos = list;
this.inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
Also inside your getView() method inflate layout like:
if (convertView == null){
view = inflater.inflate(R.layout.combo_list_item, parent , false);
Im trying to implement a RecyclingView that contains a CardView which contains a GridView. Not getting any errors just nothing is showing. Just a white screen when I try to run the app.
public class MainActivity extends AppCompatActivity {
TextView mWeatherTemp, mWeatherDescript;
RecyclerView.Adapter adapter;
Context context;
GridView gridView;
String[] mTime = {
"1:00",
"2:00",
"3:00",
"4:00",
"5:00",
"6:00",
"7:00",
"8:00",
"9:00",
"10:00",
"11:00",
};
String[] mDegreeTemp = {
"8°",
"12°",
"43°",
"100°",
"32°",
"12°",
"58°",
"39°",
"29°",
"86°",
"70°",
};
int[] imageId = {
R.mipmap.ic_launcher
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = getApplicationContext();
Toolbar mToolbar = (Toolbar) findViewById(R.id.mMainToolbar);
setSupportActionBar(mToolbar);
mToolbar.setBackgroundColor(ContextCompat.getColor(this, R.color.weather_cool));
mWeatherTemp = (TextView) findViewById(R.id.tvWeatherTemp);
mWeatherDescript = (TextView) findViewById(R.id.tvWeatherText);
Typeface robotDisplay3 = Typeface.createFromAsset(getApplicationContext().getAssets(),
"font/Roboto-Regular.ttf");
mWeatherTemp.setTypeface(robotDisplay3);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.mHourlyRV);
HourlyGridAdapter adapter = new HourlyGridAdapter(getApplicationContext(), mTime, mDegreeTemp, imageId);
gridView = (GridView) findViewById(R.id.hourlyGridView);
gridView.setAdapter(adapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.settings, menu);
return super.onCreateOptionsMenu(menu);
}
}
public class HourlyGridAdapter extends BaseAdapter {
private Context mContext;
private String[] mTime;
private String[] mDegreeTemp;
private final int[] imageId;
public HourlyGridAdapter(Context context, String[] mTime, String[] mDegreeTemp, int[] imageId) {
mContext = context;
this.imageId = imageId;
this.mDegreeTemp = mDegreeTemp;
this.mTime = mTime;
}
#Override
public int getCount() {
return 0;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.hourly_single, null, false);
holder = new ViewHolder();
holder.timeText = (TextView) convertView.findViewById(R.id.timePlaceHolder);
holder.degreeText = (TextView) convertView.findViewById(R.id.degreePlaceHolder);
holder.weatherImage = (ImageView) convertView.findViewById(R.id.weatherIconHolder);
holder.timeText.setText(mTime[position]);
holder.degreeText.setText(mDegreeTemp[position]);
holder.weatherImage.setImageResource(imageId[position]);
} else {
holder = (ViewHolder) convertView.getTag();
}
return convertView;
}
static class ViewHolder {
TextView timeText, degreeText;
ImageView weatherImage;
}
}
Layout:
<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.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
card_view:cardCornerRadius="6dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/tvDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TODAY" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/forecast_card_divider" />
<GridView
android:id="#+id/hourlyGridView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:horizontalSpacing="12dp"
android:numColumns="4"
android:verticalSpacing="12dp" />
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
<?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:orientation="vertical">
<TextView
android:id="#+id/timePlaceHolder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/timePlaceHolderText"
android:layout_gravity="center"/>
<ImageView
android:id="#+id/weatherIconHolder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#mipmap/ic_launcher"
android:layout_gravity="center"/>
<TextView
android:id="#+id/degreePlaceHolder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="12°"
android:layout_gravity="center"/>
</LinearLayout>
Im not even sure if having a GridView inside a CardView all inside a recycled view is possible. Any help trying to create this would be creately appreicated.
PS. I know im not calling recyclerView thats declared as that doesnt work and does crash the app and the GridView is null. Not really sure what to do here. Not sure if I need to create an adapter for the recyclerview as all the textViews and ImageView is in the grid not the cardview.
You are initializing and setting adapter for gridview which is inside each item of recyclerview not in recycler adapter but in activity. Consider removing all gridview-related code to recyclerview's adapter.
i have group of of images url in array of string ,now i want to display them in view pager , i tried to display images from folders and it's worked .but when i used array of string ,the images don't show . so what's the problem? that is part of my code.
ViewPager viewPager;
CustomerAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String [] urls={"https://www.nasa.gov/sites/default/files/styles/image_card_4x3_ratio/public/thumbnails/image/pia20645_main.jpg?itok=dLn7SngD","http://www.gettyimages.pt/gi-resources/images/Homepage/Hero/PT/PT_hero_42_153645159.jpg","http://humminglove.com/wp-content/uploads/2013/08/l-is-l.jpg"};
viewPager = (ViewPager)findViewById(R.id.view_pager);
adapter = new CustomerAdapter(this,urls);
viewPager.setAdapter(adapter);
}
that is adapter
public class CustomerAdapter extends PagerAdapter{
private int[] images = {R.mipmap.img1,R.mipmap.img2,R.mipmap.img3,R.mipmap.img4};
private Context ctx;
private String[] urls;
private LayoutInflater inflater;
public CustomerAdapter(Context ctx,String []urls){
this.ctx = ctx;
this.urls=urls;
}
#Override
public int getCount() {
return urls.length;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return (view ==(LinearLayout)object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
inflater = (LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.swip,container,false);
ImageView img =(ImageView)v.findViewById(R.id.imagee);
TextView tv = (TextView)v.findViewById(R.id.textView);
Picasso.with(ctx).load(urls[position]).into(img);
tv.setText("Image :"+position);
container.addView(v);
return v;
}
#Override
public void destroyItem(View container, int position, Object object) {
container.refreshDrawableState();
}
}
that's my main_activity xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
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="web.blu_ray91111.example.commyc.newwww.MainActivity">
<android.support.v4.view.ViewPager
android:id ="#+id/view_pager"
android:layout_height="300dp"
android:layout_width="match_parent"
>
</android.support.v4.view.ViewPager>
swip.xml
<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:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="25dp"
android:text="Hello world!"
android:id="#+id/textView"
android:textStyle="bold"
android:layout_marginTop="30dp"
android:gravity="center" />
<ImageView
android:layout_marginTop="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/imagee"
/>
In your case it is not clear why it didn't loaded.
1) It might take time to load big images
2) Some network error occurred on loading images
So I am you to use placeholders to coverup the error and on loading time of images.
Picasso.with(mContext).load(fileImage)
.placeholder(R.drawable.placeholder_img)
.error(R.drawable.error_placeholder_img).into(img)
Check you can access the url by normal browser
I have a Custom Listview that it is updated from a EditText component in a dialog. I have the custom row, the adapter class and the custom dialog all working but I can't seem to trigger the code in the adatper class that would add the text from the edit text control to the list. Here is my activity code, let me know if you want the adapter code. It worked before I added the custom row and adapter to the list :(
Symptom of problem: emailAdapter.notifyDataSetChanged(); does nothing
public class InvitePlayers_Activity extends Activity {
ListViewAdapter emailAdapter = null;
ImageView imgView_mail;
ImageView imgView_confirm;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE); //remove title bar
setContentView(R.layout.activity_inviteplayers);
//Generate list View from ArrayList
displayListView();
}
private void displayListView() {
//assign controls
final ListView listView = (ListView) findViewById(R.id.listView_invitePlayers);
imgView_mail = (ImageView)findViewById(R.id.imgView_mail);
//Test data
ArrayList<String> inviteNew = new ArrayList<String>();
final ArrayList<ArrayList<String>> inviteList = new ArrayList<ArrayList<String>>();
emailAdapter = new ListViewAdapter(this,inviteList);
listView.setAdapter(emailAdapter);
// Assign adapter to ListView
listView.setTextFilterEnabled(true);
//Edit listeners
imgView_mail.setOnClickListener(new View.OnClickListener() {
public void onClick(View view)
{
//variables
final String enteredMail = "testListViewEntry";
final ArrayList<ArrayList<String>> inviteList = new ArrayList<ArrayList<String>>();
ArrayList<String> invite = new ArrayList<String>();
invite.add(0, enteredMail);//add first email
invite.add(1,"icon_invitestatussent.png"); //add first status icon
inviteList.add(invite);
emailAdapter.notifyDataSetChanged();
listView.setAdapter(emailAdapter);
}
});
}
}
Adapter code as requested
public class ListViewAdapter extends BaseAdapter {
private Activity context;
ArrayList<ArrayList<String>> inviteDetails = new ArrayList<ArrayList<String>>();
public ListViewAdapter(Activity context, ArrayList<ArrayList<String>> inviteDetails ) {
this.inviteDetails = inviteDetails;
this.context = context;
}
#Override
public int getCount() {
return inviteDetails.size();
}
#Override
public Object getItem(int i) {
return inviteDetails.get(i).get(0);
}
#Override
public long getItemId(int i) {
return i;
}
public View getView(int position, View view, ViewGroup parent){
//Inflater
LayoutInflater inflater = context.getLayoutInflater();
//get row view
if (view == null) {
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
view = mInflater.inflate(R.layout.list_item_email, null);
}
//assign controls
final TextView textView_playerEmail = (TextView) view.findViewById(R.id.textView_playerEmail);
ImageView imgView_inviteStatus = (ImageView) view.findViewById(R.id.imgView_inviteStatus);
//Assign control values that are dynamic
textView_playerEmail.setText(inviteDetails.get(position).get(0));
imgView_inviteStatus.setImageResource(R.drawable.icon_invitestatussent);
return view;
}
#Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
}
}
Custom row xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp"
android:id="#+id/textView_playerEmail"
android:textColor="#color/white"
android:text="item1">
</TextView>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imgView_inviteStatus" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imgView_remove"
android:src="#drawable/btn_cancel" />
</LinearLayout>
The activity layout
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="20"
android:background="#color/yellow"
android:layout_margin="20dp"
android:padding="5dp">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:weightSum="1"
android:gravity="left|center">
<ImageView
android:layout_width="45dp"
android:layout_height="34dp"
android:id="#+id/imgView_mail"
android:src="#drawable/btn_mail"
android:layout_weight="0.22"
android:padding="3dp" />
</LinearLayout>
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/listView_invitePlayers"
android:layout_gravity="center_horizontal" />
</LinearLayout>
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:id="#+id/btn_confirm"
android:src="#drawable/btn_confirm"
android:clickable="false"
android:adjustViewBounds="true"
android:layout_gravity="center_horizontal"
android:padding="2dp"
android:layout_weight="1" />
</LinearLayout>
</FrameLayout>
Well, for what we discussed, you wanted something like this:
When you want to make a custom ListView, you have to write your own adapter. In this particular case I'm subclassing the BaseAdapter class.
This custom adapter will take hold of my data model, and will inflate the data to my ListView rows.
First, I'll create the XML of my custom row. You can see the code below.
item_mail.xml
<?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"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test text"
android:id="#+id/tv_mail"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/iv_icon"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="#android:drawable/ic_menu_report_image" />
</RelativeLayout>
Here I've created a row that displays a text and an image.
Now, I'll create my custom adapter to handle this XML. As you can see below.
MailAdapter.java
public class MailAdapter extends BaseAdapter {
private static final String LOG_TAG = MailAdapter.class.getSimpleName();
private Context context_;
private ArrayList<ArrayList<String>> mailitems;
public MailAdapter(Context context, ArrayList<ArrayList<String>> mailitems) {
this.context_ = context;
this.mailitems = mailitems;
}
#Override
public int getCount() {
return mailitems.size();
}
#Override
public Object getItem(int position) {
return mailitems.get(position).get(0);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
context_.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.item_mail, null);
}
TextView tv_mail = (TextView) convertView.findViewById(R.id.tv_mail);
ImageView iv_icon = (ImageView) convertView.findViewById(R.id.iv_icon);
String mail = mailitems.get(position).get(0);
String icon = mailitems.get(position).get(1);
Log.d(LOG_TAG,"Mail: " + mail + " mail_icon: " + icon);
tv_mail.setText(mail);
// iv_icon.setImageURI(); Here you can do whatever logic you want to update your image, using URI's, ID's, or something else.
return convertView;
}
}
Ok. Now we have everything to make this work. In your Activity class, do something like that:
activity_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=".MainActivity">
<TextView
android:text="#string/hello_world"
android:id="#+id/tv_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/tv_header">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add mail"
android:id="#+id/button"
android:layout_gravity="center" />
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/listView" />
</LinearLayout>
</RelativeLayout>
MainActivity.java
public class MainActivity extends ActionBarActivity {
private int numMail = 1; // Dummy int to create my items with different numbers.
private MailAdapter mailAdapter; // Your custom adapter.
private ArrayList<ArrayList<String>> mailItems; // This is going to be your data structure, everytime you change it, call the notifyDataSetChanged() method.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bt = (Button) findViewById(R.id.button);
ListView lv_mail = (ListView) findViewById(R.id.listView);
mailItems = new ArrayList<>();
mailAdapter = new MailAdapter(this,mailItems);
lv_mail.setAdapter(mailAdapter);
bt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addItem(); // The method I'm using to insert the item. Look for it below.
}
});
}
// Here I'm creating a new ArrayList, and appending it to my 'mailItems' Array. After that, I'm notifying the adapter that my data changed.
private void addItem() {
ArrayList<String> mail = new ArrayList<>();
mail.add(0,"mail " + numMail++);
mail.add(1,"path_to_image"); // Depending on what you want to do, put your path, URI, or whatever other way you want to store that image data.
mailItems.add(mail); // Inserting the data on the ArrayList.
mailAdapter.notifyDataSetChanged(); // Notifying the adapter that my ArrayList was modified.
}
}
This should do the trick.
I guess your problem was that you weren't updating the same ArrayList that was in your custom adapter. That's why when you called notifyDataSetChanged()nothing happened, I mean. You were creating a new ArrayList, which wasn't the same that was in your adapter. So here's what I did... I've made the ArrayList global, and then I've used it in my custom adapter constructor. After that, when the user triggers the onClick() method of my button, I'm inserting some new data on my global Array, and then I'm notifying the adapter that the data changed.
You can read a little more about that here and I've found a similar question here, which you can read as well.
Edit: Another related question, which might be an interesting read.
I have a gridview on my app that is being populated by my webpage, the thing is that i have the Image and the name of the image but the text it's being showed at a side and not below of the image, how can i achieve that?
Thanks.
This is my code:
public class ListViewAdapter2 extends BaseAdapter {
// Declare Variables
Context context;
LayoutInflater inflater;
ArrayList<HashMap<String, String>> data;
ImageLoader imageLoader;
HashMap<String, String> resultp = new HashMap<String, String>();
String coment;
public String img;
public int imga;
public ListViewAdapter2(Context context,
ArrayList<HashMap<String, String>> arraylist) {
this.context = context;
data = arraylist;
imageLoader = new ImageLoader(context);
}
#Override
public int getCount() {
return data.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
public void addItems(ArrayList<HashMap<String, String>> arraylist) {
if(data != null) {
data.addAll(arraylist);
} else {
data = arraylist;
}
}
public View getView(final int position, View convertView, ViewGroup parent) {
// Declare Variables
final String enlace;
View itemView = convertView;
RecordHolder holder = null;
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
itemView = inflater.inflate(R.layout.listview_item2, parent, false);
// Get the position
holder = new RecordHolder();
resultp = data.get(position);
// Locate the TextViews in listview_item.xml
// Locate the ImageView in listview_item.xml
holder.imagen = (ImageView) itemView.findViewById(R.id.snapshotcam);
holder.nombrecam = (TextView) itemView.findViewById(R.id.nombrecam);
itemView.setTag(holder);
// Capture position and set results to the TextViews
// Capture position and set results to the ImageView
// Passes flag images URL into ImageLoader.class
imageLoader.DisplayImage(resultp.get(MainActivity.IMAGEN), holder.imagen);
holder.nombrecam.setText(resultp.get(MainActivity.NOMBRECAM));
enlace = (resultp.get(MainActivity.ENLACE));
holder.imagen.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Intent i=new Intent(context,VideoPlayer.class);
i.putExtra("enlace", enlace);
context.startActivity(i);
}
});
return itemView;
}
static class RecordHolder {
ImageView imagen;
TextView nombrecam;
}
}
<?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=".MainActivity">
<GridView
android:id="#+id/gridcams"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:columnWidth="150dp"
android:gravity="center"
android:numColumns="auto_fit"
android:stretchMode="columnWidth" >
</GridView>
</RelativeLayout>
<?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:padding="5dp" >
<ImageView
android:id="#+id/snapshotcam"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginRight="5dp">
</ImageView>
<TextView
android:id="#+id/nombrecam"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textSize="9sp" >
</TextView>
</LinearLayout>
You forgot to change your item layout orientation to horizontal. try this change
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="5dp" >
<ImageView
android:id="#+id/snapshotcam"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginRight="5dp">
</ImageView>
<TextView
android:id="#+id/nombrecam"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textSize="9sp" >
</TextView>
</LinearLayout>