In my application i am trying to populate a wheel adapter using setter and getter method as shown in my Post Class.
class Post {
private String imageList;
private String country_name;
private String country_code;
public void setImageList ( String imageList){
this.imageList = imageList;
}
public String getImageList (){
return imageList;
}
public void setCountryName ( String country_name){
this.country_name = country_name;
}
public String getCountryName (){
return country_name;
}
...
}
My wheelAdapter class is as follows:
public class SecondWheelAdapter extends AbstractWheelTextAdapter {
ArrayList<convertor_pst> PostList = new ArrayList<convertor_pst>();
public ImageLoader imageLoader;
// Countries names
private String countries[] =
new String[] {"EUR", "USD","EUR", "USD","EUR", "USD","EUR", "USD","EUR", "USD","EUR", "USD"};
// Countries flags
private int flags[] = new int[] {R.drawable.eur, R.drawable.usd,R.drawable.eur, R.drawable.usd,R.drawable.eur, R.drawable.usd,R.drawable.eur, R.drawable.usd,R.drawable.eur, R.drawable.usd,R.drawable.eur, R.drawable.usd};
/**
* Constructor
*/
Convertor main;
public SecondWheelAdapter(Context context) {
super(context, R.layout.country_layout, NO_RESOURCE);
setItemTextResource(R.id.country_name);
}
#Override
public View getItem(int index, View cachedView, ViewGroup parent) {
View view = super.getItem(index, cachedView, parent);
ImageView img = (ImageView) view.findViewById(R.id.flag);
img.setImageResource(flags[index]);
return view;
}
#Override
public int getItemsCount() {
return countries.length;
}
#Override
protected CharSequence getItemText(int index) {
return countries[index];
}
I am trying to replace this array
// Countries names
private String countries[] =
new String[] {"EUR", "USD","EUR", "USD","EUR", "USD","EUR", "USD","EUR", "USD","EUR", "USD"};
with values stored in ArrayList<> but i don't know how to modify countries[] so that it accepts data from my PostList.get(id).getCountryName(); and next i need to set It in setItemTextResource(R.id.country_name);
Please give me a hint or a tutorial to follow. I get this wheel adapter from github it comes with a library but i am having dificulty.
Optimized solution:
Instead of managing different String Arrays or ArrayList, I would suggest you to create one ArrayList, it would be easy to manage single ArrayList.
I mean to say remove countries[] and flags[] and create Single ArrayList<Post> type.
Related
everybody! Today I was trying to solve the next problem: I've created room database for List of languages, prefill it with five ready object for different one's and then I was trying to transfer them into spinner adapter something like that:
Entity and DAO code for the Language object:
#Entity
public class Language {
#PrimaryKey
private long id;
#ColumnInfo(name = "language")
private String language;
public Language(String language) {
this.language = language;
}
public static Language[] populateData() {
return new Language[]{new Language("English"), new Language("French"), new Language(
"Spanish"), new Language("Russian"), new Language("Italian")};
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
#Dao
public interface LanguageDao {
#Query("SELECT * FROM language")
List<Language> getAll();
#Insert
void insertAll(Language... languages);
}
Further I created database object with Singleton in the AppDatabase class like that:
#Database(entities = {Language.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
private static AppDatabase INSTANCE;
public abstract LanguageDao languageDao();
public synchronized static AppDatabase getInstance(Context context) {
if (INSTANCE == null) {
INSTANCE = buildDatabase(context);
}
return INSTANCE;
}
private static AppDatabase buildDatabase(final Context context) {
return Room.databaseBuilder(context, AppDatabase.class, "my-database")
.addCallback(new Callback() {
#Override
public void onCreate(#NonNull SupportSQLiteDatabase db) {
super.onCreate(db);
Executors.newSingleThreadScheduledExecutor().execute(new Runnable() {
#Override
public void run() {
getInstance(context).languageDao()
.insertAll(Language.populateData());
}
});
}
})
.allowMainThreadQueries()
.build();
}
}
As you can see I've inserted prefill data of language objects into the instance of Database. I know that's allowMainThreadQueries() method is not recommended here (just use it to simplify current training).
Further, I've created the following method which returns spinner object and put it into activity code:
private Spinner createLanguageSpinner(){
Spinner spinner = findViewById(R.id.language_spinner);
List<Language> languages = AppDatabase.getInstance(this).languageDao().getAll();
List<String>languageStrings = new LinkedList<>();
for(int i = 0; i < languages.size(); i++){
languageStrings.add(languages.get(i).getLanguage());
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_dropdown_item_1line,
languageStrings);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
return spinner;
}
My problem is here:
List<Language> languages = AppDatabase.getInstance(this).languageDao().getAll();
I can't fill current List with predefined objects, which is resulted into empty spinner without options to choose. Could you tell where i'm getting wrong? I also would like to hear opinions about how can I simplify the creating of adapter.
I'm a bit late to the party, but in case if someone has this question too.
The problem is that you're trying to insert new objects without the PrimaryKey id value. As the result you're getting an empty table in the db.
You either should to set id value manually, e.g.:
#Entity
public class Language {
...
public Language(long id, String language) {
this.id = id; // or create method to generate a unique id as a PrimaryKey value must be unique
this.language = language;
}
public static Language[] populateData() {
return new Language[]{
new Language(1, "English"),
new Language(2, "French"),
new Language(3, "Spanish"),
new Language(4, "Russian"),
new Language(5, "Italian")
};
}
}
Or use the autoGenerate property of the PrimaryKey to let SQLite generate the unique id:
#PrimaryKey(autoGenerate = true)
private long id;
See the reference for more information.
No other changes in your code are required.
For the second question:
I also would like to hear opinions about how can I simplify the
creating of adapter
You can create a custom adapter for your spinner and pass a List<Language> to it directly:
public class MyAdapter extends BaseAdapter implements SpinnerAdapter {
private LayoutInflater mInflater;
private List<Language> mItems;
public MyAdapter(Context context, List<Language> items) {
mInflater = LayoutInflater.from(context);
mItems = items;
}
#Override
public int getCount() {
return mItems.size();
}
#Override
public Object getItem(int position) {
return mItems.get(position);
}
#Override
public long getItemId(int position) {
return mItems.get(position).getId();
}
// This is for the default ("idle") state of the spinner.
// You can use a custom layout or use the default one.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
view = mInflater.inflate(R.layout.spinner_item, parent, false);
}
Language item = (Language) getItem(position);
TextView textView = view.findViewById(R.id.text);
textView.setText(item.getTitle());
return view;
}
// Drop down item view as stated in the method name.
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
view = mInflater.inflate(R.layout.spinner_dropdown_item, parent, false);
}
Language item = (Language) getItem(position);
TextView textView = view.findViewById(R.id.text);
textView.setText(item.getTitle());
return view;
}
}
In your Activity:
List<Language> languages = AppDatabase.getInstance(this).languageDao().getAll();
Spinner spinner = findViewById(R.id.spinner);
MyAdapter myAdapter = new MyAdapter(this, languages);
spinner.setAdapter(myAdapter);
See BaseAdapter and SpinnerAdapter reference.
Or you can use ArrayAdapter and simply override toString method of your object to determine what text will be displayed for the item in the list (reference):
#Entity
public class Language {
...
#NonNull
#Override
public String toString() {
// A value you want to be displayed in the spinner item.
return language;
}
}
and in your Activity:
List<Language> languages = AppDatabase.getInstance(this).languageDao().getAll();
Spinner spinner = findViewById(R.id.spinner);
// Pass your list as the third parameter. No need to convert it to List<String>
ArrayAdapter<Language> adapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, languages);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
I process and setup content which is being delivered as a String which includes http links (http://..) and (can include) normal text (info, mirror, ...).
I am trying to set the normal text as headers in my recylcerview.
This all needs to happen dynamically as I do not know upfront if the String includes normal text and if it is included, how many normal text items there are.
So the recylcerview (could) should look like this:
http://www.link1.com
MIRROR
https://www.link2.com
https://www.link3.com
INFO
http://www.link4.com
http://www.link5.com
Now it looks like this:
MIRROR
http://www.link1.com
http://www.link2.com
http://www.link3.com
According the log it looks ok:
/testpackage.com E/ITEM: https://link1.com
/testpackage.com E/ITEM: MIRROR
/testpackage.com E/ITEM: https://link2.com
/testpackage.com E/ITEM: https://link3.com
I am having trouble getting the headers in the right position in the recyclerview.
I already looked up some solutions and I did read about several possibilities like SectionedRecyclerViewAdapter but I wouldn`t know how to implement it for my needs.
I guess the tricky part of my problem is it needs to be setup dynamically.
My code till now:
SectionViewHolder class:
public class SectionViewHolder extends RecyclerView.ViewHolder {
public TextView name;
public SectionViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.sectionHeader);
}
}
Activity where I setup things:
#EActivity(R.layout.downloads_activity)
public class DownloadsActivity extends BaseActivity {
String outPut;
RecyclerView recyclerView;
AdapterSectionRecycler adapterRecycler;
List<SectionHeader> sectionHeaders;
...
#AfterViews
public void init() {
int i = 0;
List<Child> childList = new ArrayList<>();
sectionHeaders = new ArrayList<>();
//initialize RecyclerView
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
//setLayout Manager
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setHasFixedSize(true);
...
// GET RID OF BAD HTML and SPLIT AS OF <br/>
String html = outPut.replaceAll("<br/></a>", "</a>");
String[] lines = html.split("<br/>");
...
// loop and process URL links and normal text
for (String str : Arrays.asList(lines)) {
Jsoup.parse(str).text();
str.split(",");
// function to parse the URL links and normal text from String
String item = unescapeJavaString(String.valueOf(Html.fromHtml(str)));
if (!str.contains("Use following links")) {
// Add URL links to list
if (item.startsWith("http")) {
childList.add(new Child(item));
}
// Add section headers
if (!item.startsWith("http")) {
sectionHeaders.add(new SectionHeader(childList, item, i));
}
}
Log.i("ITEM", item);
}
adapterRecycler = new AdapterSectionRecycler(this, sectionHeaders);
recyclerView.setAdapter(adapterRecycler);
}
SectionHeader class:
public class SectionHeader implements Section<Child>, Comparable<SectionHeader> {
List<Child> childList;
public String sectionText;
int index;
public SectionHeader(List<Child> childList, String sectionText, int index) {
this.childList = childList;
this.sectionText = sectionText;
this.index = index;
}
#Override
public List<Child> getChildItems() {
return childList;
}
public String getSectionText() {
return sectionText;
}
#Override
public int compareTo(SectionHeader another) {
if (this.index > another.index) {
return -1;
} else {
return 1;
}
}
}
ChildViewHolder:
public class ChildViewHolder extends RecyclerView.ViewHolder {
public TextView name;
public ChildViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.child);
}
}
Child class:
public class Child {
String name;
public Child(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
My AdapterSectionRecycler:
public class AdapterSectionRecycler extends SectionRecyclerViewAdapter<SectionHeader, Child, SectionViewHolder, ChildViewHolder> {
Context context;
public AdapterSectionRecycler(Context context, List<SectionHeader> sectionHeaderItemList) {
super(context, sectionHeaderItemList);
this.context = context;
}
#Override
public SectionViewHolder onCreateSectionViewHolder(ViewGroup sectionViewGroup, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.section_item, sectionViewGroup, false);
return new SectionViewHolder(view);
}
#Override
public ChildViewHolder onCreateChildViewHolder(ViewGroup childViewGroup, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.child, childViewGroup, false);
return new ChildViewHolder(view);
}
#Override
public void onBindSectionViewHolder(SectionViewHolder sectionViewHolder, int sectionPosition, SectionHeader sectionHeader) {
sectionViewHolder.name.setText(sectionHeader.sectionText);
}
#Override
public void onBindChildViewHolder(ChildViewHolder childViewHolder, int sectionPosition, int childPosition, Child child) {
childViewHolder.name.setText(child.getName());
}
}
Thanks in advance for the help, my code below is taken in a Text File and Displaying it in a ListView, i have Name and youtube in one Line inside the text field.
but what i am looking at trying to do is get the youtube String inside the text file and pass that to my new Activity class as a webview to play the video
just wondering how can this be done, how can i pass this String into my Setters inside my Model class in order to get an Instance of it, do i need to convert String to ArrayListString ?
public class menuFragment extends ListFragment {
ArrayList<model> songList = new ArrayList<model>();
public String[] listSongs = new String[]{};
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.list_fragment, container, false);
loadSongs();
return view;
}
public void loadSongs() {
try {
Resources ResFiles = getResources();
InputStream ReadDbFile = ResFiles.openRawResource(R.raw.songs);
byte[] Bytes = new byte[ReadDbFile.available()];
ReadDbFile.read(Bytes);
String DbLines = new String(Bytes);
listSongs = DbLines.split(",");
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, listSongs);
setListAdapter(adapter);
} catch (Exception e) {
}
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Intent i = new Intent(getActivity(), playVid.class);
model selectedSong = MainController.getInstance().getSongs().get(position);
i.putExtra("selectedSong", selectedSong);
startActivity(i);
}
public class model implements Serializable {
private String name;
private String url;
public model(String name, String url) {
this.name=name;
this.url = url;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl(){
return url;
}
public void setUrl(String url){
this.url = url;
}
public class MainController
{
private static MainController instance;
private ArrayList<model> songList;
private MainController()
{
this.songList = new ArrayList<model>();
}
public static MainController getInstance()
{
if(instance == null)
{
instance = new MainController();
}
return instance;
}
public void addFlight(String name, String singer, String url)
{
model f = new model(name,singer,url);
this.songList.add(f);
}
public ArrayList<model> getSongs()
{
return this.songList;
}
Suggestion class name should be start with capital - Model.
You have only three variables to pass to another activity, so you can have three putExtra with your intent no need for ArrayList, Sir.
Model selectedSong = MainController.getInstance().getSongs().get(position);
i.putExtra("name", selectedSong.getName());
i.putExtra("singer", selectedSong.getSinger());
i.putExtra("url", selectedSong.getUrl());
startActivity(i);
And inside onCreate of another Activity, we can access these three values like this way,
Intent mIntent = getIntent();
String name = mIntent.getStringExtra("name");
String singer = mIntent.getStringExtra("singer");
String url = mIntent.getStringExtra("url");
I have a SherlockFragmentActivity class that collects values from a server and loads it in to my database. This SherlockFragmentActivity as 3 Fragment called the Book, Video and Audios. Each of them are meant to show values that were downloaded into the db. By challenge now is when I open my UI i dont get to see the values on the fragments not until I start clicking each fragment before the values get populated into the list in the fragment. And I even notice a continuous addition of this values. My fragment class is pasted below.
public class BooksFragment extends SherlockListFragment{
TextView textview = null;
String CategoryID = null;
ArrayList<HashMap<String,String>> listBooks = null;
IDatabaseHelper databaseHelper = null;
Activity activity = null;
Context context = null;
ListAdapter adapter = null;
public BooksFragment(){
super();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.books, container, false);
// do your view initialization heres
textview = (TextView)view.findViewById(R.id.textView1);
return view;
}
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
listBooks = new ArrayList<HashMap<String,String>>();
}
#Override
public void onStart() {
super.onStart();
Bundle bundle =this.getArguments();
if(bundle != null){
CategoryID = bundle.getString("CategoryID");
}
this.initializeComponents();
this.populateListView();
}
#Override
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
activity = getActivity();
context = activity.getBaseContext();
databaseHelper= new DatabaseHelper(context);
}
//Now we are going to initialize components of the fragment
private void initializeComponents(){
ListView listview = getListView();
listview.setOnItemClickListener(listener);
}
//list item click listener
private OnItemClickListener listener = new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// TODO Auto-generated method stub
}
};
//This method would be used to collect content from the database and populate the listview item
private void populateListView(){
MedicalBookModel[] booksmodel = this.databaseHelper.ReturnBooks(CategoryID);
if(booksmodel != null){
for(MedicalBookModel book : booksmodel){
HashMap<String,String> bookMap = new HashMap<String,String>();
bookMap.put(MedicalBookModel.MedicalBookModel_ID, book.getID());
bookMap.put(MedicalBookModel.MedicalBookModel_Name,book.getName());
Log.i("values",book.getName());
listBooks.add(bookMap);
}
}
adapter = new SimpleAdapter(context, listBooks,R.layout.list_book,new String[]{ "ID","Name"}, new int[]{ R.id.bookId, R.id.bookName});
setListAdapter(adapter);
}
}
For that you have several solutions :
1- Using the Application instance singleton which is global
2- Creating your own global class to manage your data
3- Use a service bound to the activity (or not) and call backs (maybe intent and broadcast receivers)
4- Pass your object as parceable in argument when adding the fragment
Note that sometimes you will need to invalidate views to force datas to refresh
EXEMPLE OF PARCEABLE OBJECT
public class ImageObject implements Parcelable {
/**
* ATTRIBUTES
*/
protected String _idPicture;
protected String _idAlbum;
protected String _name;
protected String _fileName;
protected String _imageUrl;
protected String _hierarchy;
public ImageObject(String _idPicture, String _idAlbum, String _name, String _fileName, String _imageUrl, String _hierarchy) {
super();
this._idPicture = _idPicture;
this._idAlbum = _idAlbum;
this._name = _name;
this._fileName = _fileName;
this._imageUrl = _imageUrl;
this._hierarchy = _hierarchy;
}
public ImageObject(Parcel in) {
String[] data = new String[6];
in.readStringArray(data);
this._idPicture = data[0];
this._idAlbum = data[1];
this._name = data[2];
this._fileName = data[3];
this._imageUrl = data[4];
this._hierarchy = data[5];
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public ImageObject createFromParcel(Parcel in) {
return new ImageObject(in);
}
public ImageObject[] newArray(int size) {
return new ImageObject[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringArray(new String[] { this._idPicture, this._idAlbum, this._name, this._fileName, this._imageUrl, this._hierarchy });
}
}
Im using Custom class to fill Adapter on ListView
Class looks like that:
package com.example.raidplanner;
public class RaidWpis {
private int id;
private int id_gildia;
private String nazwa;
private int schemat;
private int data_zapis;
private int data_start;
private int opis;
private int id_officer;
private int nick_officer;
private int typ;
public RaidWpis(int id,String nazwa) {
setNazwa(nazwa);
setId(id);
}
public int getId(){
return id;
}
public void setId(int id){
this.id = id;
}
public String getNazwa() {
return nazwa;}
public void setNazwa(String nazwa) {
this.nazwa = nazwa;
}
public String toString() {
return this.nazwa;
}
public String toString2() {
return this.id+" - "+nazwa;
}
}
In my activity Im using this code
RaidWpis[] items = {
new RaidWpis(1, "aaaa"),
new RaidWpis(3, "bbbb"),
new RaidWpis(6, "cccc"),
new RaidWpis(11, "dddd"),
new RaidWpis(17, "eeee"),
};
mainListView = (ListView) findViewById( R.id.mainListView );
ArrayAdapter<RaidWpis> raidList = new ArrayAdapter<RaidWpis>(this, R.layout.simplerow, items);
// Create ArrayAdapter using the raid list.
mainListView.setAdapter(raidList);
Now how to add new items to items array. Finaly I want to fill that items array with data from json data (passed from PHP)
I did it, just changed some code to that:
ArrayList<RaidWpis> raid_list = new ArrayList<RaidWpis>();
raid_list.add(new RaidWpis(1, "aaaa"));
raid_list.add(new RaidWpis(3, "bbb"));
raid_list.add(new RaidWpis(5, "ccc"));
ArrayAdapter<RaidWpis> raidList=new ArrayAdapter<RaidWpis>(this, R.layout.simplerow, raid_list);