I am messing around creating a "slide in"(facebook style) menu for Android, this menu will be rendered as a clickable ListView using onItemClickListener. However, when i use a custom adapter for the listview it shows nothing.
The activity which runs it is my "Root activity" which means all other activities extends it. If i place the same code in another activity it can render the listview using this adapter just fine. Also, .setOnItemClickListener seems to do nothing in the root activity. Something does not get setup like it should when this view is created, any ideas? This is the code:
public class RootActivity extends Activity {
public static final String KEY_TITLE = "title";
public static final String KEY_ID = "id";
ActionBar actionBar;
ListView slideMenu;
ListMenuAdapter adapter;
ArrayList<HashMap<String, String>> menuOptions;
private String[] menuItems={"Budget","Charts","By category"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.rootview);
menuOptions = new ArrayList<HashMap<String, String>>();
slideMenu = (ListView) findViewById(R.id.slideMenuList);
slideMenu.setSaveEnabled(false);
HashMap<String, String> map;
for(int i = 0 ; i<menuItems.length ; i++ ) {
map = new HashMap<String, String>();
map.put(KEY_TITLE, menuItems[i]);
map.put(KEY_ID, ""+i);
menuOptions.add(map);
}
adapter = new ListMenuAdapter(this, menuOptions);
slideMenu.setAdapter(adapter);
Log.println(9, "slidemendeb2", ""+slideMenu.getAdapter().getCount());
slideMenu.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
Log.println(9, "Testitemclick", ""+arg0);
}
});
}}
A sample of another activity which exends RootActivity:
public class SpentMain extends RootActivity {
public static final String KEY_TITLE = "title";
public static final String KEY_ID = "id";
ArrayList<Tag> tags;
ArrayList<Integer> tagInts = new ArrayList<Integer>();
TagDataSource tagDataSource;
Button costButton;
EditText sum;
Boolean removed = false;
ActionBar actionBar;
CheckBox checkBox;
ListView list;
ListCheckboxAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.rootview);
costButton = (Button) findViewById(R.id.costadd);
sum = (EditText) findViewById(R.id.editText1);
ArrayList<HashMap<String, String>> tagsList = new ArrayList<HashMap<String, String>>();
tagDataSource = new TagDataSource(this);
tagDataSource.open();
tags = tagDataSource.getAllTags();
tagDataSource.close();
HashMap<String, String> map;
for(int i = 0 ; tags.size()>i ; i++ ) {
map = new HashMap<String, String>();
map.put(KEY_TITLE, tags.get(i).getTitle().toString());
map.put(KEY_ID, tags.get(i).getId().toString());
tagsList.add(map);
}
list=(ListView)findViewById(R.id.list);
adapter = new ListCheckboxAdapter(this, tagsList);
list.setAdapter(adapter);
// Row click event
list.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
for(int i = 0; tagInts.size()>i; i++) {
if(tagInts.get(i)==position) {
tagInts.remove(i);
removed = true;
}
}
if(removed==false) {
tagInts.add(position+1);
}
removed = false;
for(int i=0; i<((ViewGroup)view).getChildCount(); ++i) {
View nextChild = ((ViewGroup)view).getChildAt(i);
if(nextChild.getClass()==android.widget.CheckBox.class) {
checkBox = (CheckBox) nextChild;
if(checkBox.isChecked()==true) {
checkBox.setChecked(false);
} else {
checkBox.setChecked(true);
}
}
}
}
});}
As i said, if i use this adapter to render it within SpentMain it works fine but not within RootActivity. Any help is greatly appreciated.
Ok so i managed to fix the problem, what i did was to move the code out of onCreate in RootActivity and into its on method "buildSideMenu()". I then call that method in my SpentMain.class onCreate method like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.rootview);
super.buildSideMenu();
}
I noticed that if i call super.buildSideMenu() before setContentView(R.layout.rootview) it will not work. So the problem was that since super.onCreate was being run before setContentView some things had probably not been set up properly at the time my menu was being built. Hope this can help someone else!
Related
I created an ArrayAdapter for a ListView, and defined the TextView text of the element with the value "msg" of the ArrayList<HashMap<Object, Object>, up to that point all right, but when I create another element, the first element changes the text to the new "msg" value, does anyone know the error? (Text from Portuguese to English, sorry if the translation is wrong)
Class ListViewAdapter
public class ListViewAdapter extends ArrayAdapter
{
ArrayList<HashMap<Object,Object>> items;
public ListViewAdapter(Context context,ArrayList<HashMap<Object,Object>> items)
{
super(context, R.xml.chat, items);
this.items = items;
}
#Override
public View getView(int position, View view, ViewGroup parent)
{
if (view == null)
{
view = LayoutInflater.from(getContext()).inflate(R.xml.chat, parent, false);
}
TextView text_name = view.findViewById(R.id.text_name);
TextView text_message = view.findViewById(R.id.text_message);
text_message.setText(items.get(position).get("msg").toString());
return view;
}
}
MainAcrivity:
public class MainActivity extends Activity
{
public static ListView list_chat;
public static EditText edit_message;
public static Button button_send;
public static ArrayList<HashMap<Object,Object>> list_map = new ArrayList<>();
public static HashMap<Object,Object> user_map;
public static HashMap<Object,Object> chat_map;
public static HashMap<Object,Object> send_map;
public static LayoutInflater inflaterChat;
public static String BUILD;
public static Texture texture;
public static ListViewAdapter chatAdapter;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
list_chat = findViewById(R.id.list_chat);
edit_message = findViewById(R.id.edit_message);
button_send = findViewById(R.id.button_send);
BUILD = Build.ID.replace(".", "");
chatAdapter = new ListViewAdapter(this, list_map);
list_chat.setAdapter(chatAdapter);
button_send.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
chat_map = new HashMap<>();
chat_map.put("msg", edit_message.getText());
list_map.add(chat_map);
chatAdapter.notifyDataSetChanged();
}
});
}
}
I discovered the error, I put "getText ()" in a HashMap value, and when the ListView was updated, instead of getting a value already defined, it executed the getText () command again Ex: Set String to " .getText ()" instead of "HashMap " My solution was to get the text in a String and then set the value of the HashMap with that String
HashMap<Object,Object> chat_map = new HashMap<>();
String message = String.valueOf(edit_message.getText());
chat_map.put("msg", message);
list_chat_map.add(chat_map);
I have an ArrayList of my custom model class which I am instantiating by URL of images taken from Internet in my Home_Fragment using an AsyncTask
The first time the List is created it has 12 items/URL's from the website.
Now, I am passing these on a FullscreenView Activity that is linked to my ViewPager Adapter
-> I have set an onLoadMoreListener in my Home_Fragment that adds more items to the ArrayList, now I want to add those to my ViewPager Adapter dynamically,
How can I accomplish this?
Home_Fragment
class ReadHTML extends AsyncTask<String, Integer, String> {
List list;
#Override
protected String doInBackground(String... params) {
try {
Document document = Jsoup.connect(params[0]).get();
Element wall = document.select("ul.postul").first();
//Log.i("LIST ", wall.toString());
Elements url = wall.getElementsByAttribute("src");
list = url.eachAttr("src");
for (int i = 0; i < list.size(); i++) {
wallpaperNumber++;
String string = //Dummy
String septemp[] = //Dummy2
sep[1] = "http://" + string
wallpapersModelArrayList.add(new WallpapersModel(
string,///
sep[1],
"jpg",
wallpaperNumber
));
}
}catch (Exception e){}
return null;
}
Fullscreen Activity
setContentView(R.layout.fullscreen_activity_view);
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
viewPager = findViewById(R.id.view_pager);
arrayList = getIntent().getParcelableArrayListExtra("array");
final int pos = getIntent().getIntExtra("position", 0);
fullScreenSwipeAdapter = new
FullScreenSwipeAdapter(FullWallpaperViewActivity.this, arrayList);
viewPager.setAdapter(fullScreenSwipeAdapter);
viewPager.setCurrentItem(pos);
viewPager.setOnTouchListener(new View.OnTouchListener(){}
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {}
ViewPager Adapter
public FullScreenSwipeAdapter(Activity activity, ArrayList<WallpapersModel> arrayList) {
this.activity = activity;
this.arrayList = arrayList;
Fresco.initialize(activity);
}
#Override
public int getCount() {
return this.arrayList.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == (object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
layoutInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = layoutInflater.inflate(R.layout.fullwallpaper_view_layout, container, false);
draweeView = v.findViewById(R.id.full_image_view);
draweeView.setImageURI(arrayList.get(position).getWallpaperFullURL());
container.addView(v);
return v;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((CoordinatorLayout)object);
}
First make a new instance of your ArrayAdapter and set all the new items like this:
public class Activity() extends AppCompatActivity {
CustomArrayAdapter mArrayAdapter;
ViewPager mViewPager;
public void updateViewpager(){
mArrayAdapter = new ArrayAdapter(context, itemList); // old items with new items
mViewPager.setAdapter(mArrayAdapter);
mArrayAdapter.notifyDataSetChanged();
}
...
Hope it helps,
After adding new items to ArrayList, just notify your adapter of the changes using -
arrayAdapter.notifyDataSetChanged();
I am making a small MP3 Player for android.
For my project I wrote a class (MP3Finder) that returns the located songs in an ArrayList of HashMap.
Until now, my app just displays the songs located on the sdcard
in a listview from which an user can start playing a song.
Now I would like that a user should be able to add different songs to a playlist.
For this reason I made a songlist activity with a listview that contains all the
songs as checkedTextView items.
The problem is that I don't know, how to store the checked (selected by the user) songs from the songlist
back into an ArrayList of HashMap, which is to be send to the playlist activity.
I hope you understand what I want to do.
Here is the source code of my SongListActivity:
public class SongListActivity extends AppCompatActivity {
// List of mp3 files
ArrayList<HashMap<String, String>> MP3List = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button isChecked = (Button) findViewById(R.id.btn_is_checked);
final ListView listView = (ListView) findViewById(R.id.list_view);
MP3Finder mp3Finder = new MP3Finder();
// Get all mp3's from sdcard
this.MP3List = mp3Finder.getMP3List();
// Add items to ListView
ListAdapter adapter = new SimpleAdapter(this, MP3List, R.layout.activity_item, new String[] { "mp3Title" }, new int[] {
R.id.mp3_title});
listView.setAdapter(adapter);
listView.setOnItemClickListener(new CheckBoxClick());
listView.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
isChecked.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SparseBooleanArray checked = listView.getCheckedItemPositions();
int len = listView.getCount();
for (int i = 0; i < len; i++) {
if (checked.get(i)) {
// ...here is the part, where I want to store the selected songs back
// in an ArrayList of HashMap...
}
}
}
});
}
public class CheckBoxClick implements AdapterView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
CheckedTextView checkedTextView = (CheckedTextView) view;
if (checkedTextView.isChecked()) {
Toast.makeText(MainActivity.this, "checked", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "unchecked", Toast.LENGTH_SHORT).show();
}
}
}
Any help or suggestions would be appreciated.
First of all you need to declare your ArrayList as static so that it could persist across activities.
static ArrayList<HashMap<String, String>> MP3List = new ArrayList<>();
Now on button click, you need to create a new HashMap and put it inside MP3List
isChecked.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
HashMap<String,String> hashmap = new HashMap();
SparseBooleanArray checked = listView.getCheckedItemPositions();
int len = listView.getCount();
for (int i = 0; i < len; i++) {
if (checked.get(i)) {
String path = //Get your path here;
String title = // Get your title here;
hashmap.put(path,title);
}
}
MP3list.add(hashmap);
}
});
So as soon as you click a button in SongListActivity, it will go through all the items in a for loop and put checked items in the HashMap. When the loop is over, you can add the HashMap inside the ArrayList.
In my MainActivity I have a listview with two lines of text for each row. Only the first line is written when the app is started, the second line must be written based on the things processed by an AsyncTask class. When I try to do it, the first item of the listview gets all the values AsyncTask gives, because I don't understand how to update only the second line of the listview for each item, without rewriting the whole listview.
Every textView has its own id in the xml layout file. How can I do it in the onPostExecute()?
Here's the code:
In MainActivity onCreate():
final ListView listview = (ListView) findViewById(R.id.listview);
final String[] values = new String[10];
for(int i=0;i<10;i++){
//do stuff to write the values[] elements
}
MySimpleArrayAdapter adapter = new MySimpleArrayAdapter(this, values);
listview.setAdapter(adapter);
MySimpleArrayAdapter class:
public class MySimpleArrayAdapter extends ArrayAdapter<String> {
private final Context context;
private final String[] values;
int position=0;
public MySimpleArrayAdapter(Context context, String[] values) {
super(context, R.layout.list_layout, values);
this.context = context;
this.values = values;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.list_layout, parent, false);
TextView firstLine = (TextView) rowView.findViewById(R.id.label);
TextView secondLine = (TextView) rowView.findViewById(R.id.sublabel);
firstLine.setText(values[position]);
secondLine.setText(""); //I prefer to write an empty string for the secondLine
return rowView;
}
}
The AsyncTask:
private class Process extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
//do stuff
}
#Override
protected void onPostExecute(String message) {
TextView secondLine = (TextView) findViewById(R.id.sublabel);
//This of course udpdates only the secondLine of the first item of listview
secondLine.setText(processedValues);
}
}
pass the TextView as a parameter to the AsyncTask as follows
private class Process extends AsyncTask<Void, Void, String> {
private WeakReference<TextView> weakTextView;
public Process(TextView textView){
weakTextView = new WeakReference<TextView>(textView);
}
#Override
protected String doInBackground(Void... params) {
//do stuff
}
#Override
protected void onPostExecute(String message) {
TextView tv = weakTextView.get();
if(tv!=null){
tv.setText(message);
}
}
}
you call this in your getView as
Process p = new Process(yourTextView);
p.execute();
//method number two
private class Process extends AsyncTask<TextView, Void, String> {
private WeakReference<TextView> weakTextView;
#Override
protected String doInBackground(TextView... params) {
if(params == null||params.length=0){
return null;
}
TextView tv = (TextView)params[0];
weakTextView = new WeakReference<TextView>(tv);
//do stuff
}
#Override
protected void onPostExecute(String message) {
TextView tv = weakTextView.get();
if(tv!=null){
tv.setText(message);
}
}
}
you call this in your getView as
Process p = new Process();
p.execute(yourTextView);
//method 3
just update the underline data object of this list adapter
and call adapter.notifyDataSetChanged();
which will call getView again
this method, in most cases, is preferable to the other 2 above, unless you are displaying images from the internet
MainActivity.class:
public class MainActivity extends ListActivity {
public static final String TITLE = "title";
public static final String SUBTITLE = "subtitle";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/// setContentView(R.layout.activity_main);
setListAdapter(createAdapter());
}
protected Map<String, String> createElement(String title, String subtitle)
{
Map<String, String> result = new HashMap<String, String>();
result.put(TITLE, title);
result.put(SUBTITLE, subtitle);
return result;
}
public List<Map<String, String>> getData()
{
List<Map<String, String>> result = new ArrayList<Map<String,String>>();
result.add(createElement("Hello", ""));
result.add(createElement("Hello2", ""));
result.add(createElement("Hello3", ""));
return result;
}
public ListAdapter createAdapter()
{
SimpleAdapter adapter = new SimpleAdapter(this, getData(),
android.R.layout.simple_list_item_2,
new String[]{TITLE, SUBTITLE, },
new int[]{android.R.id.text1, android.R.id.text2});
adapter.areAllItemsEnabled();
return adapter;
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Intent i = null;
switch (position)
{
case 0:
i = new Intent(this, GalleryUrlActivity.class);
break;
case 1:
i = new Intent(this, GalleryFileActivity.class);
break;
case 2:
i = new Intent(this, SonEklenen.class );
break;
}
startActivity(i);
}
}
How to add edittext and button inside listview
i want to add a button and edittext inside MainActivity class. how can i do that?
Please read this tutorial first: http://www.vogella.com/articles/AndroidListView/article.html. There is a section specifically of developing custom adapters which is what you want to do, but you need to have more information on how ListView works to understand it so I recommend reading the whole tutorial.