Dynamically adding a button in Fragment - java

Hello im trying to add a button but i keep getting this error:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.LinearLayout.addView(android.view.View, android.view.ViewGroup$LayoutParams)' on a null object reference
this is my code, it works well in regular activity, its not working as a fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fav, container, false);
lSecond = (LinearLayout) v.findViewById(R.id.lSecond);
lThird = (LinearLayout) v.findViewById(R.id.lThird);
return v;
}
public void bCreate(String i)
{
LinearLayout.LayoutParams btnParams = new LinearLayout.LayoutParams(matchParent, wrapContent);
Button btnNew = new Button(this.getActivity());
btnNew.setBackgroundResource(R.drawable.button);
btnNew.setTextColor(Color.parseColor("#ffffff"));
btnNew.setText(i);
scale = getResources().getDisplayMetrics().density;
int top = (int) (5 * scale + 0.5f);
int bot = (int) (5 * scale + 0.5f);
if (Second < Third)
{
int left = (int) (10 * scale + 0.5f);
int right = (int) (5 * scale + 0.5f);
btnParams.leftMargin = left;
btnParams.rightMargin = right;
btnParams.topMargin = top;
btnParams.bottomMargin = bot;
lSecond.addView(btnNew, btnParams);
Second++;
btnNew.setOnClickListener(listen);
}
bCreate is getting called in onCreate, and String i - is a String from database

bCreate() is being called too early. You're trying to access lSecond before it has a value. Call bCreate() in onCreateView() just before the return.

Related

How can I set text in Fragment between Adapter?

How can set text in Fragment between Adapter?
Explain:
Fragment use explor.xml layout
Adapter use store_list.xml layout
Because I had used LocationListener in Fragment, so when I got the latitude and longitude, as same time I still got lat and lng from firebase DB.
double radLat1 = rad(camperSiteModel1.getCamperSiteLatitude());
double radLat2 = rad(latitude);
double a = radLat1 - radLat2;
double b = rad(camperSiteModel1.getCamperSiteLongitude()) - rad(longitude);
double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
+ Math.cos(radLat1) * Math.cos(radLat2)
* Math.pow(Math.sin(b / 2), 2)));
s = s * EARTH_RADIUS * 1.609344;
s = Math.round(s * 10000) / 10000;
Log.i("distance",s+"");
distance.setText(s);
I set distance = view.findViewById(R.id.distance); in Fragment and set distance.setText(s);
fragment.java
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_explore, container,false);
distance = view.findViewById(R.id.distance);
readDate();
}
private void readCampSite(){
//Firebase code ...
distance.setText(s);
}
Should I set TextView distance in adapter?
Adapter.java
public class ViewHolder extends RecyclerView.ViewHolder {
distance = itemView.findViewById(R.id.distance);
}
And final, how can setText in distance in fragment list.xml?
I got this error:
Attempt to invoke virtual method void
android.widget.TextView.setText(java.lang.CharSequence) on a null
object reference
Where has problem?

Setting margin on view in RelativeLayout programmatically doesn't have any affect

In Android, I create an ImageView in the Java code and set its layout parameters: width, height and top margin before adding it to the main layout (RelativeLayout). The width and height are applied successfully, but the margin doesn't have any affect on the image view position. The actual top margin stays 0.
How to apply the top margin to views? The code is below.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initClouds();
}
private void initClouds() {
addCloud(R.drawable.cloud1, R.dimen.cloud1_top_margin);
addCloud(R.drawable.cloud2, R.dimen.cloud2_top_margin);
}
private void addCloud(int imageResId, int topMarginResId) {
RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.mainLayout);
ImageView cloud = new ImageView(this);
int height = (int) getResources().getDimension(R.dimen.cloud_height);
int width = (int) getResources().getDimension(R.dimen.cloud_width);
ViewGroup.MarginLayoutParams params = new ViewGroup.MarginLayoutParams(width, height);
params.topMargin = (int) getResources().getDimension(topMarginResId);
cloud.setImageResource(imageResId);
mainLayout.addView(cloud, params);
}
}
For setting the margin for a view inside RelativeLayout you should use RelativeLayout.LayoutParams . Change your code like this ,
private void addCloud(int imageResId, int topMarginResId) {
RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.mainLayout);
ImageView cloud = new ImageView(this);
int height = (int) getResources().getDimension(R.dimen.cloud_height);
int width = (int) getResources().getDimension(R.dimen.cloud_width);
RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(width, height);
param.topMargin = (int) getResources().getDimension(topMarginResId);
cloud.setImageResource(imageResId);
mainLayout.addView(cloud, param);
}

How to limit view movement in onTouch to a parentview in Android?

This seems to be easy to state but there seems no straight forward implementation. I want to limit the movement of an imageview to its direct parent. I couldn't find examples related to this. Can somebody help me with an example for this?
I actually want to achieve a motion where the leaf in middle is moved, the leaf at the top should move to bottom and the bottom leaf should move to the middle and the middle leaf should move to top position. This coupled with the elevation of the middle leaf. Please refer to the image below.
I have tried to achieve this by using the rect of the parent view in onTouch of the view but that doesn't seem to work. Tried to achieve this listview and recyclerview but that seems to add a lot of complexity to a simple requirement.
Here is my code
public class Main6Activity extends AppCompatActivity {
ImageView imageView;
private int _xDelta;
private int _yDelta;
View view;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main6);
imageView = (ImageView)findViewById(R.id.img1);
view = findViewById(R.id.imglayout);
final Rect rect = new Rect(view.getLeft(),view.getTop(),view.getRight(),view.getBottom());
imageView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
if(event.getAction() == MotionEvent.ACTION_DOWN){
LinearLayout.LayoutParams lParams = (LinearLayout.LayoutParams) imageView.getLayoutParams();
_xDelta = X - lParams.leftMargin;
_yDelta = Y - lParams.topMargin;
}
if (event.getAction() == MotionEvent.ACTION_MOVE){
if(isViewContains(X,Y)){
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) imageView.getLayoutParams();
layoutParams.leftMargin = X - _xDelta;
layoutParams.topMargin = Y - _yDelta;
layoutParams.rightMargin = -250;
layoutParams.bottomMargin = -250;
imageView.setLayoutParams(layoutParams);
}
}
return true;
}
});
}
private boolean isViewContains(int rx,int ry) {
int[] l = new int[2];
view.getLocationOnScreen(l);
Rect rect1 = new Rect(l[0], l[1], l[0] + view.getWidth(), l[1] + imageView.getHeight());
return rect1.contains(rx, ry);
}
}

Nothing Showing When Dynamically Creating a Relative Layout

Hi I've been having problems with my code with null pointer exceptions (see my other questions) so I've gone for creating my view dynamically.
Here's my code:
public class HarvestLifeActivity extends Activity implements OnTouchListener {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//add touch listeners for buttons : assign each a name and link it.
View MoveUp = findViewById(R.id.up);
MoveUp.setOnTouchListener(this); // use (this) to link to the current onTouchListener references in class declaration above.
View MoveDown = findViewById(R.id.down);
MoveDown.setOnTouchListener(this);
View MoveLeft = findViewById(R.id.left);
MoveLeft.setOnTouchListener(this);
View MoveRight = findViewById(R.id.right);
MoveRight.setOnTouchListener(this);
}
#Override
protected void onStart() {
super.onStart();
Drawable standing = getResources().getDrawable(R.drawable.test_circle);
//code to convert character size from pixel to dp
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
float logicalDensity = metrics.density;
int pxToConv = 50;
int convToDp = (int) (pxToConv / logicalDensity + 0.5);
RelativeLayout characterContainer = new RelativeLayout(this);
RelativeLayout.LayoutParams characParams = new RelativeLayout.LayoutParams(convToDp, convToDp);
characParams.addRule(RelativeLayout.CENTER_IN_PARENT);
characterContainer.setBackgroundDrawable(standing);
characterContainer.setId(101);
}
// Process button clicks
public boolean onTouch(View v, MotionEvent event) {
switch(v.getId()){
case R.id.up:
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//as long as up button is pressed it will keep moving character up
while (event.getAction() == MotionEvent.ACTION_DOWN)
{
RelativeLayout characterContainer = (RelativeLayout) findViewById(101);
Drawable walking = getResources().getDrawable(R.drawable.test_circle_red);
int startX = characterContainer.getLeft();
int startY = characterContainer.getTop();
int defaultWidth = characterContainer.getWidth();
int defaultHeight = characterContainer.getHeight();
//create new position for character 1 pixel closer to the top of screen
int newX = startX - 1;
int newY = startY;
//remove character
RelativeLayout view = (RelativeLayout) characterContainer;
ViewGroup owner = (ViewGroup) view.getParent();
owner.removeView(view);
//re make character in new position created above and assign background as walking forwards animation
RelativeLayout.LayoutParams characParams = new RelativeLayout.LayoutParams(defaultWidth,defaultHeight);
characParams.leftMargin = newY;
characParams.topMargin = newX;
characterContainer.setLayoutParams(characParams);
characterContainer.setBackgroundDrawable(walking);
}
break;
// when button is let go of
case MotionEvent.ACTION_UP:
RelativeLayout characterContainer = (RelativeLayout) findViewById(101);
Drawable standing = getResources().getDrawable(R.drawable.test_circle);
characterContainer.setBackgroundDrawable(standing);
default:
break;
}
return true;
case R.id.down:
.. ..
}
return true;
}
}
When I run it the created layout is not there.
Is there something I've missed?
You are creating a RelativeLayout object, but never setting it as the content for the window...
make your onCreate Look like this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Cut these lines out of onStart();
RelativeLayout characterContainer = new RelativeLayout(this);
RelativeLayout.LayoutParams characParams = new RelativeLayout.LayoutParams(convToDp, convToDp);
characParams.addRule(RelativeLayout.CENTER_IN_PARENT);
characterContainer.setBackgroundDrawable(standing);
characterContainer.setId(101);
setContentView(characterContainer);
//add touch listeners for buttons : assign each a name and link it.
/*View MoveUp = findViewById(R.id.up);
MoveUp.setOnTouchListener(this); // use (this) to link to the current onTouchListener references in class declaration above.
View MoveDown = findViewById(R.id.down);
MoveDown.setOnTouchListener(this);
View MoveLeft = findViewById(R.id.left);
MoveLeft.setOnTouchListener(this);
View MoveRight = findViewById(R.id.right);
MoveRight.setOnTouchListener(this);*/
}
you are not adding your created layout to the existing view.
thats your problem.
addview(your_layout);

Problem passing a parameter to a different class

I've got a rather peculiar problem. I am trying to pass a number of parameters to a method in a different class, and three out of the four parameters are being passed just fine. The fourth, however, is returning 0 (zero) regardless of what I seem to do.
I am initializing the second class, ImageLoader, without any issues.
Here's the call in question - I've added comments to explain my problem:
imageLoader.DisplayImage(coverFileNames.get(position), Main.this, (ImageView) convertView, position); // coverFileNames.get(position) works great and returns the correct filename based on the position - position on its own, however, doesn't!
And here's the DisplayImage method:
public int position;
public void DisplayImage(String fileUrl, Activity activity, ImageView imageView, final int pos) {
position = pos; // this is 0 no matter what I do
imageViews.put(imageView, fileUrl);
queuePhoto(fileUrl, activity, imageView);
imageView.setImageResource(R.drawable.noposterlarge);
}
Any ideas? Thanks.
EDIT:
Here's the GetView method:
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = (ImageView) new ImageView(Main.this);
}
// Create new file for the file path of the movie
File file = new File(videoUrls.get(position));
// Create variables for potential custom art check
boolean potentialImage = false;
String ImageFile = null;
String[] potentialImageFiles = new String[]{file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf(".")) + ".jpg",
file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf(".")) + ".jpeg",
file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf(".")) + ".JPG",
file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf(".")) + ".JPEG"};
// Check if each file exists and return if one does
for (String potentialFile : potentialImageFiles) {
if (!potentialImage) {
if (new File(potentialFile).exists()) {
potentialImage = true;
ImageFile = potentialFile;
}
}
}
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
options.inPreferredConfig = Config.RGB_565;
// Check if there's a custom cover art
if (potentialImage) {
Log.d("TEST", "POS: " + position); // this returns the correct value
imageLoader.DisplayImage(ImageFile, Main.this, (ImageView) convertView, position);
} else {
Log.d("TEST", "POS: " + position); // this returns the correct value
imageLoader.DisplayImage(coverFileNames.get(position), Main.this, (ImageView) convertView, position);
}
return convertView;
}
And again, here's the DisplayImage method:
public void DisplayImage(String fileUrl, Activity activity, ImageView imageView, final int pos) {
Log.v("Testing", "position = " + pos); // This returns 0, which is not correct
imageViews.put(imageView, fileUrl);
queuePhoto(fileUrl, activity, imageView);
imageView.setImageResource(R.drawable.noposterlarge);
}
this is simply impossible
Add to top of DisplayImage
Log.v("DisplayImage", "position = " + position);
If it is 0
Change the calling code from
imageLoader.DisplayImage(coverFileNames.get(position), Main.this, (ImageView) convertView, position);
to
imageLoader.DisplayImage(coverFileNames.get(position), Main.this, (ImageView) convertView, 2);
Now, will it show 2? It must
It means that in your calling code in the line imageLoader.DisplayImage() position has always been 0 for some reason.
coverFileNames.get(position) is always returning the String at position=0
Try removing the final modifier from your DisplayImage function
public void DisplayImage(String fileUrl, Activity activity, ImageView imageView, int pos)

Categories