ViewPager app not working (Eclipse) - java

I need your help on this. I am going to make an app using ViewPager and I since I never been programming for android before I thought it would be good to make a sample app first. I want to use the ViewPager a little bit differently than the classic list-of-items-style so I made an app that will show all the colors (or every 10th color) from #000000 to #FFFFFF.
It doesn't work. I've started the app on the emulator but I just get a white screen. If the default position of the ViewPager when starting is 0 then the color should be black. And when I try to make a breakpoint the program doesn't stop, or it's never reaching the point. I'm using eclipse.
These are the files of the project
MainActivity.java
package com.example.colorswipe;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;
public class MainActivity extends Activity {
private ViewPager mPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPager=(ViewPager)this.findViewById(R.id.pager);
mPager.setAdapter(new MyAdapter());
}
private class MyAdapter extends PagerAdapter {
#Override
public int getCount() {
return 0xFFFFFF/10;
}
#Override
public boolean isViewFromObject(View arg0, Object arg1) {
// TODO Auto-generated method stub
return false;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
ColorView view=new ColorView(container.getContext());
view.setBackgroundColor(android.graphics.Color.parseColor(String.format("#%06X", position*10)));
view.setText(position);
container.addView(view);
return view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View)object);
}
}
}
activity_main.xml
<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.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
ColorView.java
package com.example.colorswipe;
import android.content.Context;
import android.widget.LinearLayout;
import android.widget.TextView;
public class ColorView extends LinearLayout {
private TextView tv;
public ColorView(Context context) {
super(context);
LayoutParams params=new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
this.setLayoutParams(params);
TextView tv=new TextView(context);
this.tv=tv;
this.addView(tv);
}
public void setText(int position) {
tv.setText(Integer.toString(position).toCharArray(), 0, Integer.toString(position).length());
}
}

EDIT - the view pager is there , but I think you don't resolve the color correctly.

I found the problem. isViewFromObject must be implemented as return arg0==arg1.

Related

Android SeekBar: Move by thumb only

I know this question was asked and somewhat answered before, but none of the solutions I found so far really worked out for me: I have a custom seekBar with a large square block for the thumb, which I draw on the fly, and I want the seekBar progress to change only when the thumb is being dragged.
Large thumb seekBar
I looked around and tried out all of the proposed solutions I could find, and some worked better then others, but they all have a big issue (for me at least): if I detect the boundaries of the thumb in order to start dragging the thumb, the onTouch ACTION_DOWN event makes the thumb jump to whatever position the pointer is on the screen, within the thumb's boundaries, of course.
If the thumb size is small, this is almost a non issue, but on a large thumb, this behavior is really annoying.
To make matters worse, if I declare a thumb offset of 0 to keep the thumb inside the seekBar, the jumping behavior changes with respect to where on the seekbar the thumb is: indetermined jump direction right in the middle of the seekbar, or it jumps to the right if the thumb is on the left half of the seekbar, or to the left if the thumb is on the right half of the seekbar.
Here's my starting code, I removed all of my failed attempts to make the seekBar's thumb move only when a drag starts:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="#+id/progressText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/mySeekbar"
app:layout_constraintVertical_bias="0.154" />
<com.example.thumbonlyseekbar.MySeekBar
android:id="#+id/mySeekbar"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_marginStart="20dp"
android:layout_marginTop="150dp"
android:layout_marginEnd="20dp"
android:indeterminate="false"
android:max="99"
android:progress="0"
android:progressDrawable="#drawable/my_seekbar"
android:thumb="#drawable/thumb"
android:thumbOffset="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
MySeekbar.java
package com.example.thumbonlyseekbar;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import androidx.annotation.NonNull;
public class MySeekBar extends androidx.appcompat.widget.AppCompatSeekBar {
Drawable mThumb;
public MySeekBar(#NonNull Context context) {
super(context);
}
public MySeekBar(#NonNull Context context, AttributeSet attrs) {
super(context, attrs);
}
public MySeekBar(#NonNull Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void setThumb(Drawable thumb) {
super.setThumb(thumb);
mThumb = thumb;
}
public Drawable getSeekBarThumb() {
return mThumb;
}
}
MainActivity.java
package com.example.thumbonlyseekbar;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.SeekBar;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
MySeekBar customSeekBar;
TextView progressValueText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
customSeekBar = findViewById(R.id.mySeekbar);
progressValueText = findViewById(R.id.progressText);
progressValueText.setText(String.valueOf(customSeekBar.getProgress()));
customSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
progressValueText.setText(String.valueOf(progress));
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
}
thumb.xml
package com.example.thumbonlyseekbar;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.SeekBar;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
MySeekBar customSeekBar;
TextView progressValueText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
customSeekBar = findViewById(R.id.mySeekbar);
progressValueText = findViewById(R.id.progressText);
progressValueText.setText(String.valueOf(customSeekBar.getProgress()));
customSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
progressValueText.setText(String.valueOf(progress));
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
}
my_seekbar.xml
package com.example.thumbonlyseekbar;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.SeekBar;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
MySeekBar customSeekBar;
TextView progressValueText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
customSeekBar = findViewById(R.id.mySeekbar);
progressValueText = findViewById(R.id.progressText);
progressValueText.setText(String.valueOf(customSeekBar.getProgress()));
customSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
progressValueText.setText(String.valueOf(progress));
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
}
If you would like to see an example of what I mean by a no-thumb-jump seekBar, please take a look at the AMPLIFi Remote app in Google Play Store (it may only work on older devices, it works on my OREO 8.1, you may need to try it in an emulator that allows downloads from Google Play if you don't have an older device). The thumb's progress is unbelievably smooth, and there's absolutely no jumping around. Whoever wrote that app did an awesome job!
Many, many thanks, any suggestion is much appreciated!

How to trigger an event when clicked in PreferenceFragmentCompat

I use androidx. In the settings fragment, I want to create the "Preference" buttons and click on them to trigger some individual events.
How can I implement a click listener on a specific Preference?
Thats some my Code:
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.appcompat.widget.Toolbar;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
public class SettingsFragment extends PreferenceFragmentCompat {
#Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.preference);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = super.onCreateView(inflater, container, savedInstanceState);
view.setBackgroundColor(getResources().getColor(R.color.graylight));
Toolbar toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);
toolbar.setTitle(R.string.action_settings);
toolbar.setLogo(R.drawable.ic_settings_white_24dp);
PreferenceManager preferenceManager = getPreferenceManager();
PreferenceScreen preferenceScreen = getPreferenceScreen();
return view;
}
}
And XML:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<PreferenceCategory
android:title="#string/setting_person"
app:initialExpandedChildrenCount="0"
app:key="profile_set">
<Preference
android:id="#+id/preference2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:key="button1"
android:summary="#string/setting_person_data"
android:title="#string/setting_person_reg"
app:icon="#drawable/ic_assignment" />
<Preference
android:key="button"
android:summary="#string/setting_avatar"
android:title="#string/setting_avatar_chg"
app:icon="#drawable/ic_wallpaper_black_24dp" />
</PreferenceCategory>
</PreferenceScreen>
As a result, I want to click on the trigger an event in MainActivity. But this is another question, now at least I should get a listen to the event, for example by calling Toast with the key of the button pressed.
Find the preference, then set a click listener on it.
public class SettingsFragment extends PreferenceFragmentCompat {
#Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.preference);
Preference preference = findPreference("button1");
preference.setOnClickListener(new OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference p) {
// Handle preference click
}
});
}
}
Please review the documentation on using Preferences:
https://developer.android.com/reference/androidx/preference/package-summary.html
https://developer.android.com/reference/androidx/preference/PreferenceFragmentCompat.html
https://developer.android.com/reference/androidx/preference/PreferenceFragmentCompat.html#findPreference(java.lang.CharSequence)
https://developer.android.com/reference/androidx/preference/Preference.OnPreferenceClickListener.html
Hope that helps!
After much torment, the solution was found as follows: (for AndroidX)
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.appcompat.widget.Toolbar;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
public class SettingsFragment extends PreferenceFragmentCompat {
#Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.preference);
Preference preferenceMap = findPreference("button");
preferenceMap.setOnPreferenceClickListener(
new Preference.OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference arg0) {
getActivity().onBackPressed();
((MainActivity) getActivity()).injectSetting("map");
return true;
}
});
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = super.onCreateView(inflater, container, savedInstanceState);
view.setBackgroundColor(getResources().getColor(R.color.graylight));
Toolbar toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);
toolbar.setTitle(R.string.action_settings);
toolbar.setLogo(R.drawable.ic_settings_white_24dp);
return view;
}
}
and in XML androidx.preference is added to the element:
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.preference.PreferenceCategory
android:title="#string/setting_person"
app:initialExpandedChildrenCount="1"
app:key="profile_set">
<androidx.preference.Preference
android:id="#+id/preference1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:key="button"
android:summary="#string/setting_person_data"
android:title="#string/setting_person_reg"
app:icon="#drawable/ic_assignment" />
<androidx.preference.Preference
android:id="#+id/preference2"
android:key="button2"
android:summary="#string/setting_avatar"
android:title="#string/setting_avatar_chg"
app:icon="#drawable/ic_wallpaper_black_24dp" />
</androidx.preference.PreferenceCategory>
</androidx.preference.PreferenceScreen>
And do not forget at build.gradle dependencies:
implementation 'androidx.preference:preference:1.1.0'
Maybe someone will need ))

TabLayout Not Binding to Viewpager

I have a fragment which hosts a TabLayout and a ViewPager. The host fragment is part of a container that switches based on the item selection of a bottom navigation bar.
For some reason, the ViewPager isn't inflating the fragments, and the TabLayout is unresponsive. When sliding left or right, the indicator stops as soon as you stop sliding, and doesn't snap like it should. And, of course, the fragments don't show.
Here is my code...I'm wondering what I am doing wrong.
PopularHolderFragment.java
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import ai.gab.android.R;
import ai.gab.android.ui.adapters.fragment.PopularFragmentsAdapter;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* Created by Andrew Quebe on 10/20/2017.
*/
#SuppressWarnings("ConstantConditions")
public class PopularHolderFragment extends Fragment {
#BindView(R.id.tabLayout)
TabLayout tabLayout;
#BindView(R.id.viewPager)
ViewPager viewPager;
public static PopularHolderFragment newInstance() {
return new PopularHolderFragment();
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_popular_holder, container, false);
ButterKnife.bind(this, view);
return view;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
viewPager.setAdapter(new PopularFragmentsAdapter(getActivity().getSupportFragmentManager()));
tabLayout.addTab(tabLayout.newTab().setText("Posts"));
tabLayout.addTab(tabLayout.newTab().setText("Users"));
tabLayout.setupWithViewPager(viewPager);
}
}
PopularFragmentsAdapter.java
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import ai.gab.android.ui.fragments.popular.PopularPostsFragment;
import ai.gab.android.ui.fragments.popular.PopularUsersFragment;
/**
* Created by Andrew Quebe on 8/7/2017.
*/
public class PopularFragmentsAdapter extends FragmentStatePagerAdapter {
public PopularFragmentsAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return PopularPostsFragment.newInstance();
case 1:
return PopularUsersFragment.newInstance();
}
return null;
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Posts";
case 1:
return "Users";
}
return super.getPageTitle(position);
}
#Override
public int getCount() {
return 2;
}
}
fragment_popular_holder.xml
<android.support.design.widget.CoordinatorLayout 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=".ui.activities.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Light">
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:elevation="2dp"
tools:targetApi="lollipop" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/util_popular_main_content" />
</android.support.design.widget.CoordinatorLayout>
util_popular_main_content.xml
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/fragment_popular_holder">
<android.support.v4.view.ViewPager
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.constraint.ConstraintLayout>
Screenshots
Also wondering why the text isn't its normal size.
Note that I do not want a toolbar in this layout, and perhaps that is my issue, but I don't see why it would be as the widgets should be able to work independently of each other.
Using the comment from Mike and AndroidSmoker74's answer, I was able to fix the TabLayout bug.
PopularWrapperFragment.java
public class PopularWrapperFragment extends Fragment {
#BindView(R.id.tabLayout)
TabLayout tabLayout;
#BindView(R.id.viewPager)
ViewPager viewPager;
public static PopularWrapperFragment newInstance() {
return new PopularWrapperFragment();
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_popular_holder, container, false);
ButterKnife.bind(this, view);
((MainActivity) getActivity()).setPagingEnabled(false);
viewPager.setAdapter(new PopularFragmentsAdapter(getChildFragmentManager()));
tabLayout.setupWithViewPager(viewPager);
return view;
}
}
PopularFragmentsAdapter.java
public class PopularFragmentsAdapter extends FragmentStatePagerAdapter {
public PopularFragmentsAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return PopularPostsFragment.newInstance();
case 1:
return PopularUsersFragment.newInstance();
}
return null;
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Posts";
case 1:
return "Users";
}
return super.getPageTitle(position);
}
#Override
public int getCount() {
return 2;
}
}
Hope someone finds this useful!
May be my answer is not correct answer for your question. I faced same issue while dealing with Fragments... Below is the mistake I did.
return super.onCreateView(inflater, container, savedInstanceState);
This was creating this kind of issue. I removed this sentence and just inflated some view from the layout files, then it was working fine.
Just check your onCreateView function it will probably solve your problem.
My point is clear here. You should return your inflated view in onCreateView function instead of super.onCreateView(inflater, container, savedInstanceState);
do the binding of pager and tabs in onCreateView. Not in the onActivityCreated.
And you don't need to manually add tabs to TabLayout, it'll do so automatically.
just get the tabs by position and set their text.
binding should be in onCreateView.

My app stopped every time when I load it

EDIT Happy New Year! To be precise ,I created a simple music app in Android Studio who read mp3 files from my internal storage. All good until I decide to put one random image on every single track on the list. (In front of the name of the song I want to appear one image).When I select one single image in 'src' at ImageView ,it works and appear to all songs. I will atach a part of my code below: Main Activity:
package com.alg.amzar.spectrum;
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("native-lib");
}
private ArrayList<Song> songList;
private ListView songView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
schimbare();
songView = (ListView)findViewById(R.id.song_list);
songList = new ArrayList<Song>();
getSongList();
Collections.sort(songList, new Comparator<Song>(){
public int compare(Song a, Song b){
return a.getTitle().compareTo(b.getTitle());
}
});
SongAdapter songAdt = new SongAdapter(this, songList);
songView.setAdapter(songAdt);
}
public void schimbare() {
int[] photos={R.drawable.img_0, R.drawable.img_1,R.drawable.img_2};
ImageView image = (ImageView) findViewById(R.id.imagine);
Random ran=new Random();
int i=ran.nextInt(photos.length);
image.setImageResource(photos[i]);
}
public void getSongList() {
ContentResolver musicResolver = getContentResolver();
Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor musicCursor = musicResolver.query(musicUri, null, null, null, null);
if(musicCursor!=null && musicCursor.moveToFirst()){
//get columns
int titleColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media.TITLE);
int idColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media._ID);
//add songs to list
do {
long thisId = musicCursor.getLong(idColumn);
String thisTitle = musicCursor.getString(titleColumn);
songList.add(new Song(thisId, thisTitle));
}
while (musicCursor.moveToNext());
}
}
public native String stringFromJNI();
}
Activity Main .xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#FF330000"
tools:context=".MainActivity" >
<ListView
android:id="#+id/song_list"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</ListView>
</LinearLayout>
Song.xml :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="songPicked"
android:orientation="vertical"
android:padding="5dp" >
<ImageView
android:layout_width="70dp"
android:id="#+id/imagine"
android:layout_height="50dp" />
<TextView
android:id="#+id/song_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF99"
android:textSize="15sp"
android:textStyle="bold"
android:layout_marginBottom="20dp"
android:layout_marginLeft="75dp"
android:layout_marginTop="-42dp"/>
</LinearLayout>
Beside this ,I've 2 more java classes. I think the problem is here ,but idk what is wrong:
public void schimbare() {
int[] photos={R.drawable.img_0, R.drawable.img_1,R.drawable.img_2};
ImageView image = (ImageView) findViewById(R.id.imagine);
Random ran=new Random();
int i=ran.nextInt(photos.length);
image.setImageResource(photos[i]);
}
Another wondering of mine is what 'deprecated' means when is I use .getDrawable.
Thanks in advance!
Logcat:
ime: FATAL EXCEPTION: main
Process: com.alg.amzar.spectrum, PID: 28677
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.alg.amzar.spectrum/com.alg.amzar.spectrum.MainActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2381)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2433)
at android.app.ActivityThread.access$800(ActivityThread.java:155)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1346)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5341)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:830)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:646)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.alg.amzar.spectrum.MainActivity.schimbare(MainActivity.java:57)
at com.alg.amzar.spectrum.MainActivity.onCreate(MainActivity.java:31)
at android.app.Activity.performCreate(Activity.java:5343)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1088)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2335)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2433) 
at android.app.ActivityThread.access$800(ActivityThread.java:155) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1346) 
at android.os.Handler.dispatchMessage(Handler.java:110) 
at android.os.Looper.loop(Looper.java:193) 
at android.app.ActivityThread.main(ActivityThread.java:5341) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:515) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:830) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:646) 
at dalvik.system.NativeStart.main(Native Method) 
My phone android version: 4.4.2 (API 19)
Target SDK Version:"19"
MinSDK Version:"14"
SongAdapter.java:
package com.alg.amzar.spectrum;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.ArrayList;
public class SongAdapter extends BaseAdapter {
private ArrayList<Song> songs;
private LayoutInflater songInf;
public SongAdapter(Context c, ArrayList<Song> theSongs) {
songs = theSongs;
songInf = LayoutInflater.from(c);
}
#Override
public int getCount() {
return songs.size();
}
#Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//map to song layout
LinearLayout songLay = (LinearLayout)songInf.inflate
(R.layout.song, parent, false);
//get title and artist views
TextView songView = (TextView)songLay.findViewById(R.id.song_title);
//get song using position
Song currSong = songs.get(position);
//get title and artist strings
songView.setText(currSong.getTitle());
//set position as tag
songLay.setTag(position);
return songLay;
}
}
In your case, findViewById(R.id.imagine) returns NULL because it doesn't exist in the layout 'activity_main', which you provided in setContentView(). findViewById() returns NULL if the view doesn't exist in current layout. R.id.imagine exists in the layout song.xml.
I think, you are trying to inflate the ListView with layout 'song'. Only after inflating you can call findViewById and setImageResource. You can done it in class SongAdapter, for each elements in ListView after inflating them.
Another suggestion, instead of using random images you can get album art of a song from MediaMetadataRetriever class. You can refer android documentation for that. But you have to solve this exception before.
Comment/ Delete function schimbare() in onCreate and edit SongAdapter like following.
package com.alg.amzar.spectrum;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.ArrayList;
public class SongAdapter extends BaseAdapter {
private ArrayList<Song> songs;
private LayoutInflater songInf;
int[] photos={R.drawable.img_0, R.drawable.img_1,R.drawable.img_2};
Random ran=new Random();
// CHECK THIS:
public SongAdapter(Context c, ArrayList<Song> theSongs) {
songs = theSongs;
// CHECK THIS:
songInf = ( LayoutInflater )c.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return songs.size();
}
#Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//map to song layout
LinearLayout songLay = (LinearLayout)songInf.inflate
(R.layout.song, null);
//get title and artist views
TextView songView = (TextView)songLay.findViewById(R.id.song_title);
// CHECK THIS:
ImageView img = (ImageView)songLay.findViewById(R.id.imagine);
//get song using position
Song currSong = songs.get(position);
//get title and artist strings
songView.setText(currSong.getTitle());
// CHECK THIS:
int i=ran.nextInt(photos.length);
img.setImageResource(photos[i]);
//set position as tag
songLay.setTag(position);
return songLay;
}
}
Deprecated mean that google no longer support this method, they telling you there is NEWER method you should use. the deprecated method is working fine FOR NOW. But some day (maybe tomorrow maybe 3 years from today) it will no longer work.
about the error, upload the log please.
The error is at line 57:
at com.alg.amzar.spectrum.MainActivity.schimbare(MainActivity.java:57)
I am not sure where line 57 is but you can check it in your code, if you still cant find the cause then update us which line is 57
public void schimbare() {
int[] photos={R.drawable.img_0, R.drawable.img_1,R.drawable.img_2};
ImageView image = (ImageView) findViewById(R.id.imagine);
Random ran=new Random();
// CHANGE photos.length to photos.length-1
int i=ran.nextInt(photos.length);
//ADD this 2 line of code below, then you can check in your Log if the problem is with the view (the view is null), or if the photos position is null.
Log.d("bug_tag",String.valueOf(photos[i]));
Log.d("bug_tag",String.valueOf(image.getId()));
image.setImageResource(photos[i]);
}

How to destroy and recreate objects in Android during runtime?

I'm developing an Android app that has to simulate a sort of Pokédex.
For now, what I want to do is simply have all 151 Pokémon printed on my device, so I can scroll them up and down.
The problem is that when I try this thing with such as 9 or 12 images there are no problems, but when I load all the 151 images (all .png), Android kills the app because it's draining too much system resources.
I've heard that there are Java methods that can (don't know how) "destroy" an object when it goes out of the display and then recreate it when it returns in the screen. Anyway if you have different suggestions on how to resolve my problem, every idea is welcome!
Here is my MainActivity:
package com.example.thefe.newsmartkedex;
import android.media.AudioManager;
import android.media.SoundPool;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GridView gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new ImageAdapter(this));
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
Toast.makeText(MainActivity.this, "" + position,
Toast.LENGTH_SHORT).show();
}
});
};
}
And here is my ImageAdapter class I use for Gridview:
package com.example.thefe.newsmartkedex;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(200, 200));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
// references to our images
private Integer[] mThumbIds = {
R.drawable.pkmn1, R.drawable.pkmn2,
R.drawable.pkmn3, R.drawable.pkmn4,
R.drawable.pkmn5, R.drawable.pkmn6,
R.drawable.pkmn7, R.drawable.pkmn8,
R.drawable.pkmn9, R.drawable.pkmn10,
R.drawable.pkmn11, R.drawable.pkmn12,
R.drawable.pkmn13, R.drawable.pkmn14,
R.drawable.pkmn15, R.drawable.pkmn16,
R.drawable.pkmn17, R.drawable.pkmn18,
R.drawable.pkmn19, R.drawable.pkmn20,
R.drawable.pkmn21, R.drawable.pkmn22,
R.drawable.pkmn23, R.drawable.pkmn24,
R.drawable.pkmn25, R.drawable.pkmn26,
R.drawable.pkmn27, R.drawable.pkmn28,
R.drawable.pkmn29, R.drawable.pkmn30,
R.drawable.pkmn31, R.drawable.pkmn32,
R.drawable.pkmn33, R.drawable.pkmn34,
R.drawable.pkmn35, R.drawable.pkmn36,
R.drawable.pkmn37, R.drawable.pkmn38,
R.drawable.pkmn39, R.drawable.pkmn40,
R.drawable.pkmn41, R.drawable.pkmn42,
R.drawable.pkmn43, R.drawable.pkmn44,
R.drawable.pkmn45, R.drawable.pkmn46,
R.drawable.pkmn47, R.drawable.pkmn48,
R.drawable.pkmn49, R.drawable.pkmn50,
R.drawable.pkmn51, R.drawable.pkmn52,
R.drawable.pkmn53, R.drawable.pkmn54,
R.drawable.pkmn55, R.drawable.pkmn56,
R.drawable.pkmn57, R.drawable.pkmn58,
R.drawable.pkmn59, R.drawable.pkmn60,
R.drawable.pkmn61, R.drawable.pkmn62,
R.drawable.pkmn63, R.drawable.pkmn64,
R.drawable.pkmn65, R.drawable.pkmn66,
R.drawable.pkmn67, R.drawable.pkmn68,
R.drawable.pkmn69, R.drawable.pkmn70,
R.drawable.pkmn71, R.drawable.pkmn72,
R.drawable.pkmn73, R.drawable.pkmn74,
R.drawable.pkmn75, R.drawable.pkmn76,
R.drawable.pkmn77, R.drawable.pkmn78,
R.drawable.pkmn79, R.drawable.pkmn80,
R.drawable.pkmn81, R.drawable.pkmn82,
R.drawable.pkmn83, R.drawable.pkmn84,
R.drawable.pkmn85, R.drawable.pkmn86,
R.drawable.pkmn87, R.drawable.pkmn88,
R.drawable.pkmn89, R.drawable.pkmn90,
R.drawable.pkmn91, R.drawable.pkmn92,
R.drawable.pkmn93, R.drawable.pkmn94,
R.drawable.pkmn95, R.drawable.pkmn96,
R.drawable.pkmn97, R.drawable.pkmn98,
R.drawable.pkmn99, R.drawable.pkmn100,
R.drawable.pkmn101, R.drawable.pkmn102,
R.drawable.pkmn103, R.drawable.pkmn104,
R.drawable.pkmn105, R.drawable.pkmn106,
R.drawable.pkmn107, R.drawable.pkmn108,
R.drawable.pkmn109, R.drawable.pkmn110,
R.drawable.pkmn111, R.drawable.pkmn112,
R.drawable.pkmn113, R.drawable.pkmn114,
R.drawable.pkmn115, R.drawable.pkmn116,
R.drawable.pkmn117, R.drawable.pkmn118,
R.drawable.pkmn119, R.drawable.pkmn120,
R.drawable.pkmn121, R.drawable.pkmn122,
R.drawable.pkmn123, R.drawable.pkmn124,
R.drawable.pkmn125, R.drawable.pkmn126,
R.drawable.pkmn127, R.drawable.pkmn128,
R.drawable.pkmn129, R.drawable.pkmn130,
R.drawable.pkmn131, R.drawable.pkmn132,
R.drawable.pkmn133, R.drawable.pkmn134,
R.drawable.pkmn135, R.drawable.pkmn136,
R.drawable.pkmn137, R.drawable.pkmn138,
R.drawable.pkmn139, R.drawable.pkmn140,
R.drawable.pkmn141, R.drawable.pkmn142,
R.drawable.pkmn143, R.drawable.pkmn144,
R.drawable.pkmn145, R.drawable.pkmn146,
R.drawable.pkmn147, R.drawable.pkmn148,
R.drawable.pkmn149, R.drawable.pkmn150,
R.drawable.pkmn151
};
}
Finally, this is the XML file
<?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: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="com.example.thefe.newsmartkedex.MainActivity">
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="90dp"
android:numColumns="auto_fit"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:gravity="center"
/>
</RelativeLayout>
Thanks for help!
First of all, I don't see any violation in your code so let's focus the pictures.
The problem is that when I try this thing with such as 9 or 12 images there are no problems, but when I load all the 151 images (all .png), Android kills the app because it's draining too much system resources.
What do you mean by 'load all the 151 images'? At the same time in the same screen? Or you just make quite a small numbers of them(like 9,12,16 etc.) seen in the view and others out of the screen?
I've heard that there are Java methods that can (don't know how) "destroy" an object when it goes out of the display and then recreate it when it returns in the screen. Anyway if you have different suggestions on how to resolve my problem, every idea is welcome!
You can't simply destroy an object by yourself and the Jvm will handle this for you when your objects are invalid or unused. As to this problem the recreation of objects that you implements in 'getView' seems no harm.
My question is: how many images did you show in one whole screen? And what size of them?
If you can provide your demo here, it will be the best to work on.
Display limited images that can fit your screen and load the other images when scrolling Gridview.
That way system wont have do to do lots of work at once. Your application gets faster also.
You can refer this link:
i want grid view with loading by scroll i have image fetch from sever but i want only 10 images view other can load when scrolling grid view

Categories