How do I get an image in my listview? - java

Currently I'm using an ArrayAdapter which I just import. As the question states I want to get images into my listviews. I'm loading information into my list using JSONObjects and storing them into my ArrayLists. I know my current method removes html tages from the JSONObjects.
public class Home extends Activity {
ListView lView;
TextView tView;
ArrayAdapter lAdapter;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home_layout);
lView = (ListView) findViewById(android.R.id.list);
//tView = (TextView) findViewById(android.R.id.);
loadList(lView);
}
public void loadList(ListView lView){
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall("URL", ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
ArrayList<String> titles = new ArrayList<String>();
ArrayList<String> body = new ArrayList<String>();
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
JSONArray entries = jsonObj.getJSONArray("entries");
for (int i = 0; i < entries.length(); i++) {
JSONObject c = entries.getJSONObject(i);
String text = c.getString("introtext");
if(text == "null"){
text = "No text here" + "\n" + "\n";
}
else {
text = android.text.Html.fromHtml(text).toString();
}
String title= c.getString("title");
String full = title + "\n" + "\n" + text;
titles.add(full);
//body.add(text);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
lAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, titles);
lView.setAdapter(lAdapter);
}
}
Any suggestions would be great help
Thanks

First create a layout same what you want to show in a row, now create a class for a custom adapter like:
public class MyAdapter extends ArrayAdapter<T>{
}
Where T represents the entity class, which represents your data model.
Now under override method:
public View getView(final int position, View convertView, ViewGroup parent) {}
Inflate your layout created for the row, and set each view as you want to show.
Don't forgot to use lazy loading for the image to load over the imageview.
Hope it will help you.

You will need to create a custom adapter that has your own Layout defined. In this layout, you can include whatever you want (including an ImageView, that you can place your image).
There are many examples, but the important thing to know in your code, is you will supply your own adapter here, and set it up a bit differently:
lAdapter = new ArrayAdapter<String>(this, R.layout.my_custom_adapter, titles);

Try to use a Base Adapter
Inflate a custom Xml having a imageview using the base adapter
You can put any views(Image,textview etc ) depending on your
requirement
Finally use picasso or imageloader to populate images using the JSON
response to your base adapter
Hope it helps, Revert back to me if you need any more help, Happy coding

You'll have to create a custom adapter instead of ArrayAdapter, so that you can use your own layout for every row, and perform any 'image loading' there. Try creating a class that extends the BaseAdapter abstract class from the framework. Also, search the web or here (in stackoverflow) you'll find tons of tutorials on how to create a custom adapter.
Since downloading and loading images can be a bit of a pain if you aren't experienced with ListViews and custom adapters, I would suggest looking up two 3rd party libraries for this job:
Picasso or Universal-Image-Loader, each one having examples on how to use them alongside with custom adapters

Related

Android Adapter not being updated

I want to display a list of match objects (match = two users having liked each other) in a recycler view with the help of an adapter.
This is my activity which is meant to display those matches:
public class MatchesActivity extends AppCompatActivity {
// variables:
private RecyclerView mMatchesRecyclerView;
private RecyclerView.Adapter mMatchItemAdapter;
private RecyclerView.LayoutManager mMatchesLayoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_matches);
mMatchesRecyclerView = findViewById(R.id.matches_recyclerView);
mMatchesRecyclerView.setNestedScrollingEnabled(false);
mMatchesRecyclerView.setHasFixedSize(true);
// set layout manager & pass it to the recycler view:
mMatchesLayoutManager = new LinearLayoutManager(MatchesActivity.this);
mMatchesRecyclerView.setLayoutManager(mMatchesLayoutManager);
// set match adapter & pass it to the recycler view:
mMatchItemAdapter = new MatchItemAdapter(getMatchesList(), MatchesActivity.this);
mMatchesRecyclerView.setAdapter(mMatchItemAdapter);
// add test items to the recycler view:
Match testMatch = new Match("abcdefgh");
matchesList.add(testMatch);
mMatchItemAdapter.notifyDataSetChanged();
Log.d("MatchesActivity", "TEST LIST: " + matchesList.toString());
}
private ArrayList<Match> matchesList = new ArrayList<Match>();
private List<Match> getMatchesList() {
Log.d("MatchesActivity", "getMatchesList function: " + matchesList.toString());
return matchesList;
}
}
And this is my adapter which is supposed to inflate the relevant layout & populate it with relevant object data:
public class MatchItemAdapter extends RecyclerView.Adapter<MatchViewholder> {
private List<Match> mMatchesList;
private Context mViewContext;
public MatchItemAdapter(List<Match> matchesList, Context context) {
this.mMatchesList = matchesList;
this.mViewContext = context;
Log.d("MatchItemAdapter", "Constructor: " + mMatchesList.toString());
}
// inflate the layout:
#Override
public MatchViewholder onCreateViewHolder(ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_matches, null, false);
RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutView.setLayoutParams(lp);
MatchViewholder matchViewholder = new MatchViewholder(layoutView);
Log.d("MatchItemAdapter", "onCreateViewHolder: " + mMatchesList.toString());
return matchViewholder;
}
// populate each row within the layout:
#Override
public void onBindViewHolder(MatchViewholder holder, int position) {
Log.d("MatchItemAdapter", "onBindViewHolder: " + mMatchesList.toString());
holder.mMatchID.setText(mMatchesList.get(position).getMatchID());
}
#Override
public int getItemCount() {
return 0;
}
}
The Match class currently only takes matchID parameter which is string. An object is created with a default image and this matchID string.
At the moment, I have no real match objects from database ready, so I wanted to check that the recycler view along with adapter are working as expected before i move on to that later.
However, when I go to Matches Activity, it is empty, showing nothing at all. As you can see from the MatchesActivity onCreate method, I created a test Match object with matchID = "abcdefgh" and then added that to the matchesList. So I am expecting the "abcdefgh" text to be passed to the adapter and to be shown in the MatchesActivity.
My log statements indicate that the Match object has been created and added to the list successfully, however, getMatchesList() function returns an empty list which is then used in the Adapter constructor too, (I think this is) causing Activity not show anything.
I am relatively new to Android and Java development, especially recycler view and adapters, but from what I gathered it seems to be as if the
mMatchItemAdapter.notifyDataSetChanged();
is not working properly as everything seems to be fine up until that point. Any help would be appreciated!
You're returning 0. What you should do instead is return the length of the mMatchesList list.
#Override
public int getItemCount() {
return mMatchesList.size();
}

why spinner view appears shrunk when called asynchronously in Android

Background
When I fill a spinner using a resource array, things work just fine:
Spinner countryCodeSpinner = (Spinner) findViewById(R.id.country_code_spinner);
countryCodeSpinner.setOnItemSelectedListener(this);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.country_codes_array, android.R.layout.simple_spinner_item);
where country codes are read from a resource:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array
name="country_codes_array">
<item>971</item>
<item>961</item>
<item>628</item>
<item>193</item>
<item>477</item>
</string-array>
</resources>
output:
Question
but when I fill up the spinner contents from an api call like so:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
..
Spinner currencySpinner = (Spinner) findViewById(R.id.currency_spinner);
populateCurrency(currencySpinner);
private void populateCurrency(final Spinner spinner) {
_currencies = new HashMap<String, String>();
final Context context = this;
// getting the contents of spinner from api call
new SyncHelper().get(CreateOrderActivity.this,
Connections.CURRENCIES(CreateOrderActivity.this),
null, null, new SyncListener() {
#Override
public void onSuccess(String data, int requestCode) {
try {
JSONObject object = new JSONObject(data);
if (object.getString("errors") == "false") {
JSONArray currenciesArray = object.getJSONObject("data")
.getJSONArray("currencies");
for (int i=0; i< currenciesArray.length(); i++) {
String currencyRef = currenciesArray.getJSONObject(i).getString("ref");
String currencyId = currenciesArray.getJSONObject(i).getString("id");
_currencies.put(currencyRef, currencyId);
}
String[] currencyrefs = Arrays.copyOf(_currencies.keySet().toArray(),
_currencies.keySet().toArray().length, String[].class);
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(context, android.R.layout.simple_spinner_item,currencyrefs);
spinner.setAdapter(adapter);
then the spinner rendered view is all shrunk like so:
even though in both cases, we're using android.R.layout.simple_spinner_item.. any idea how to fix this?
I wasn't able to reproduce the issue, for me the first example gives an output similar to the second example and second example gives the same output (No margins, height is set to wrap_content, also for the second example, I only used the same adapter constructor to simulate). The difference in behavior might be because of the different APIs (I used an emulator with API 26).
However, to me your first and desired output looks like simple_spinner_dropdown_item instead of simple_spinner_item and I was able to produce a similar spinner with simple_spinner_dropdown_item, so you might want to check it out.

updating adapter within anonymous inner class android

I'm new to Android. I'm trying to get data from Parse and update the adapter.
I'm extending my adapter from Array Adapter.
In my adapter, I have an image and an text field.
Issues I have: I'm seeing only the last element in the array in my array adapter.
This is my basic set up:
My parse method contains an inner anonymous class findCallBackMethod.
In the done method of the parse,
I'm getting the data from Parse and creating a new object to add it to my array list.
This array list is shown in my adapter.
I'm able to see my entire array result list within my done method.
I searched onto stack overflow and followed some suggestions on creating and setting the adapter within this done method.
Tried so far:
Making the adapter within the for loop. This for loop gets the data from Parse.
Tried creating a global instance for ArrayList so the arrayList is visible.
(Didn't help at all)
I cannot make my array list final as I'll creating this array list within this for loop.
Question: How do I make my adapter update the list from within this anonymous inner class?
what am i missing here?
Any help is appreciated.
Thanks!
Below is my sample of my code:
public void searchPlayer(String playerFirstName)
{
ParseQuery<ParseObject> query_players = ParseQuery.getQuery("myDataFile");
try {
query_players.whereMatches("FirstName","Patrick");
} catch (NullPointerException e) {
e.printStackTrace(); // change this to meaningful message
}
query_players.findInBackground(new FindCallback<ParseObject>()
{
public String shortName;
public int playerID;
#Override
public void done(List<ParseObject> playerList, com.parse.ParseException e) {
if (e == null)
{
d("TAG", "Retrieved: size = " + playerList.size());
for(int i=0;i<playerList.size();i++)
{
newPlayer = MySingleton.getInstance().newPlayer;
arrayOfPlayers = MySingleton.getInstance().arrayOfPlayers;
// short name is abbreviated name; got it from Parse
// create a single player
String shortName = playerList.get(i).getString("ShortName");
String firstName = playerList.get(i).getString("FirstName");
String lastName = playerList.get(i).getString("LastName");
playerID = playerList.get(i).getInt("PlayerID");
Log.d("Player", "short name: " + shortName);
//newPlayer = new Player();
// if (newPlayer != null) {
newPlayer.setPlayerShortName(shortName);
newPlayer.setPlayerFirstName(firstName);
newPlayer.setPlayerLastName(lastName);
newPlayer.setPlayerID(playerID);
newPlayer.setPhotoUrl(playerList.get(i).getString("PhotoUrl"));
Log.d("Player", "the photo url = : " + newPlayer.getPhotoUrl());
//adding the new player to the array
if (newPlayer != null) {
d("Player", "adding the new player to array list ");
arrayOfPlayers.add(newPlayer);
Log.d("Player", "the new player's last name in the arrayList " + arrayOfPlayers.get(i).getPlayerLastName());
Log.d("Player", "the new player's photo url in the arrayList " + arrayOfPlayers.get(i).getPhotoUrl());
}
//printing the playerlist:
for(Player x:arrayOfPlayers) {
Log.d(TAG,"printing the list of player's last name within the for: " + x.getPlayerLastName());
}
lvPlayerList = (ListView) view.findViewById(R.id.lvPlayerList);
aPlayerListAdapter= new PlayerSearchListArrayAdapter(getActivity(),arrayOfPlayers);
lvPlayerList.setAdapter(aPlayerListAdapter);
aPlayerListAdapter.notifyDataSetChanged();
}// end of for
/* THIS WORKS WITHIN THE INNER CLASS --- TESTED)
Log.d("Player", "the array size " + arrayOfPlayers.size());
Log.d("Player", "the player id from the arrayList " + arrayOfPlayers.get(8).getPlayerID());
Log.d("Player"," the activity in the player fragment: " + getActivity());
*/
} //end of (e==null)
else
{
d("score", "Error: " + e.getMessage());
//playerArrayList = null;
}
}// end of done
}); // end of inner class
My Adapter class:
// Adapter for the list: inflates player_list_item
public class PlayerSearchListArrayAdapter extends ArrayAdapter<Player>{
public static final String TAG = "PLAYER_SEARCH_LIST_ADAPTER";
private ImageView imvPlayer;
private TextView tvPlayerFullName;
List<Player> playerList;
LayoutInflater mInflater;
public PlayerSearchListArrayAdapter(Context context,List<Player> playerList) {
//super(context, 0 , playerList);
super(context,0,playerList);
mInflater = LayoutInflater.from(context);
this.playerList = playerList;
}
public View getView(int position, View convertView, ViewGroup parent) {
//return super.getView(position, convertView, parent);
Log.d(TAG,"inside adapter");
Log.d(TAG,"activity = " + getContext());
// get the data item for position
Player player = getItem(position);
Log.d(TAG,"player list size from within the adapter: = " + playerList.size());
Log.d(TAG,"player's last name = " + player.getPlayerLastName());
// find if the view exists. what that means if we reached the max limit
// of items to view on the screen, then Android starts to recycle the
// previous viewable list items.
// If the view does not exist, we have to create one through the inflater
View v = convertView;
if (v == null)
{
LayoutInflater inflater = LayoutInflater.from(getContext());
// v = inflater.inflate(R.layout.player_list_item,parent,false);
// check if to attach to root
v = inflater.inflate(R.layout.player_list_item,parent,false);
}
// find the ids in the tweet_item.xml
ImageView imvPlayer = (ImageView)v.findViewById(R.id.imvPlayer);
TextView tvPlayerFullName = (TextView)v.findViewById(R.id.tvPlayerFullName);
// populate the items
// ImageUri is the url of the image
String imageUri = player.getPhotoUrl();
Picasso.with(getContext()).load(imageUri).into(imvPlayer);
tvPlayerFullName.setText(player.getPlayerShortName());
return v;
}
}
My usage of singleton in this case is not correct.
Fixed the issue. I was creating the adapter and the array every single time the loop iterates.
Changing that solved the issue.

How to search within ListView with custom adapter

I looked at the following site: ListView Example
Which describes how to implement a search function in a listview which uses the default adapter and it works fine.
How can I modify it so I can use the same for a Custom Adapter for my listview?
Partial code is:
dataList = (ListView) findViewById(R.id.lvFiles);
tvQuote = (TextView) findViewById(R.id.tvDisplay);
tvQuote.setTypeface(Typeface.createFromAsset(MainActivity.this.getAssets(), "fonts/roboto.ttf"));
for (int y=0; y<strNamesOfAllah.length;y++) {
name = strNamesOfAllah[y];
meaning = strMeaning[y];
rowsArray.add(new SetRows(R.drawable.icon, name, meaning));
}
adapter = new SetRowsCustomAdapter(MainActivity.this, R.layout.customlist, rowsArray);
dataList.setAdapter(adapter);
dataList.setClickable(true);
You need to override getFilter inside of your adapter and return a new customFilter object that you create. See this answer: No results with custom ArrayAdapter Filter
Edit:
#Override
public Filter getFilter() {
if(customFilter == null){
customFilter = new CustomFilter();
}
return customFilter;
}

How to display data fetched from the database table into listview?

My Function In SQLAdapter class is
public ArrayList<Airline> getairlinedetails(String bookingdate) {
Cursor curCalllog =db.rawQuery("SELECT * FROM "+ BOOK +
" WHERE " + date +
" BETWEEN '" + startdate + "' AND '" + enddate + "'", null);
if (curCalllog != null) {
if (curCalllog.moveToFirst()) {
do {
a=new Airline();
//a.setBookingdate(curCalllog.getString(1));
a.setPickupadd(curCalllog.getString(2));
a.setCity(curCalllog.getString(3));
a.setTrip(curCalllog.getString(4));
a.setFdate(curCalllog.getString(5));
a.setFtime(curCalllog.getString(6));
a.setCdate(curCalllog.getString(7));
a.setPtime(curCalllog.getString(8));
a.setSeats(curCalllog.getInt(9));
a.setAmount(curCalllog.getInt(10));
update.add(a);
} while (curCalllog.moveToNext());
}
}
return update;
}
M Fetching data between two dates and
I Want To show the fetched data into listview please help me how to do it I m new in android development.
You can use SimpleCursorAdapter for showing Databse contents in Listview. Make instance of SimpleCursorAdapter and pass Cursor object into it. Refer this link
If you want Customized Listview, you can customize SimpleCursorAdapter by extending this with your custom adapter class.
you can follow this example :
DataManipulator.java -helper class
//to retrieve data in a list
public List<String[]> selectAll()
{
List<String[]> list = new ArrayList<String[]>();
Cursor cursor = db.query(TABLE_NAME, new String[] { "id","name","number","skypeId","address" },
null, null, null, null, "name asc");
int x=0;
if (cursor.moveToFirst()) {
do {
String[] b1=new String[]{cursor.getString(0),cursor.getString(1),cursor.getString(2),cursor.getString(3),cursor.getString(4)};
list.add(b1);
x=x+1;
} while (cursor.moveToNext());
}
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
cursor.close();
return list;
}
CheckData.java
// to show data in a list view
public class CheckData extends ListActivity {
TextView selection;
public int idToModify;
DataManipulator dm;
List<String[]> list = new ArrayList<String[]>();
List<String[]> names2 =null ;
String[] stg1;
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.check);
dm = new DataManipulator(this);
names2 = dm.selectAll();
stg1=new String[names2.size()];
int x=0;
String stg;
for (String[] name : names2) {
stg = name[1]+" - "+name[2]+ " - "+name[3]+" - "+name[4];
stg1[x]=stg;
x++;
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
this,android.R.layout.simple_list_item_1,
stg1);
this.setListAdapter(adapter);
selection=(TextView)findViewById(R.id.selection);
}
public void onListItemClick(ListView parent, View v, int position, long id) {
selection.setText(stg1[position]);
}
}
follow this link for complete tutorial
I assume you are getting data from database and there by complete ArrayList with Airline objects.
Now to display data in ListView from ArrayList<Airline>, you have to define Custom adapter class by extending either BaseAdapter or ArrayAdapter.
Here you go: How to define custom adapter for ListView?
I Want To show the fetched data into listview please help me how to do
it I m new in android development
Simpliest way is to use ArrayAdapter with build-in ListView's row layout.
ListView list = (ListView) findViewById(R.id.yourList);
ArrayList<Airline> data = db.getairlinedetails("someString");
ArrayAdapter<Airline> adapter = new ArrayAdapter<Airline>(this,
android.R.layout.simple_list_item_1, data);
list.setAdapter(adapter);
But since this you need to also override toString() method in your Airline class.
Reason is that your ArrayAdapter will convert each child(provided list of airlines) to String and if you won't override toString() you will get default string representation of object but you probably need to show for instance name of airline so your method can looks like
#Override
public String toString() {
return this.name;
}
Note:
This is simple way. But if you want to get more control over ListView and create custom list i recommend you to create own subclass of ListAdapter for example BaseAdapter and define your own Adapter. Sorry but i won't write you implementation because it requires much more code but nice examples you can find here:
Customizing Android ListView Items with Custom ArrayAdapter
Android ListView, ListActivity and ListFragment - Tutorial
Android Custom ListView with Image and Text

Categories