In my case, i want a fullscreen viewpager with a button on the top of it. It's easy in Android.
Here is the sample code
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="match_parent >
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="15dp"
android:src="#drawable/button_help" />
</RelativeLayout>
but in rn , it seems that flexbox acts like Linearlayout in Android that siblings of parent cannot overlap each other. I don't think it make sense in mobile dev since multiple layers is common in mobile dev. I got a trick to solve the issue by using position: absolute. The drawback of the solution is that alignItems take no effect if using absolute position so you need to do another trick to make button center in horizon. Is there any better way? Anything like RelativeLayout would be supported in RN? I think Relativelayout is the very efficient way to do the layout of app dev.
Here is my code of RN
render() {
var {height, width} = Dimensions.get('window');
console.log("rntest width " + width);
var mywidth = width;
return(
<View
style={styles.viewPager}>
<IndicatorViewPager
style={styles.viewPager}
initialPage={0}
onPageScroll={onPageScroll}
onPageSelected={onPageSelected}>
<View
style={styles.viewPager}>
<Image
style={styles.viewPager}
source={require('./img/1.jpg')}
resizeMode='cover'/>
</View>
<View
style={styles.viewPager}>
<Image
style={styles.viewPager}
source={require('./img/2.jpg')}
resizeMode='cover'/>
</View>
<View
style={styles.viewPager}>
<Image
style={styles.viewPager}
source={require('./img/3.jpg')}
resizeMode='cover'/>
</View>
</IndicatorViewPager>
<TouchableHighlight onPress={onPressButton} style={{width: mywidth, height: 103,
position:'absolute', left: 0, bottom: 0, alignItems: 'center'}}>
<Image
style={{width: 103, height: 103}}
source={require('./img/voice_run.png')}
/>
</TouchableHighlight>
}
</View>
);
position: absolute is not trick. It is normal solution. Think about absolute views as about another layers. So alignItems defined in previous layer will not affect current layer childs.
You do not need to use Dimensions. You can simply add right: 0 to TouchableHighlight if you need full width button.
Flexbox is not ideal but it is simple and powerful enough. I don't think something else will be introduced soon.
Related
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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=".ProfileMainActivity">
<ImageView
android:layout_width="match_parent"
android:layout_height="240dp"
android:src="#drawable/cp"
android:scaleType="centerCrop"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="240dp"
android:clipToPadding="false">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_marginBottom="8dp"
android:layout_marginRight="10dp"
/>
<ImageButton
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_gravity="top|left"
android:layout_marginTop="200dp"
android:layout_marginLeft="20dp"
android:src="#drawable/dp"
android:scaleType="centerCrop"
android:background="?attr/selectableItemBackgroundBorderless"
/>
</FrameLayout>
I need the image to be cropped within the black circle , but it doesn't happen.
Moreover I noticed that the ripple from the ImageButton touch goes out in a circular area, so I was guessing that there might be some way to fit the image within that area itself.
Dimension of Stock Image:- 495x495
I suggest you recreate the image as circular bitmap. You can use this a method like this one. Just introduce the necessary round pixels.
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) {
if (bitmap == null)
return null;
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
final float roundPx = pixels;
paint.setAntiAlias(true);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
Using a library you can easily fixed this issue> This may helps you com.mikhaellopez:circularimageview:3.0.2. Hope that it works and solve your issue
I'm trying to run flex on a ScrollView, and as long as the ScrollView has flex: 1 the scroll inside does not work.
here is the expo fiddle (that you can run this code and play with)
https://snack.expo.io/SySerKNp-
note that if you remove the flex: 1 from the ScrollView it does let scroll but then you lose the flex power ( the ability to let the red container down to push up the upper box (the ScrollView) ) so I must have a flex there.
p.s - I'm working only on android, and I haven't tested it on iPhone( I don't mind the result there )
any idea what am I missing ? why the ScrollView won't function right when it has a flex: 1 ?
thanks !
Try using flexGrow: 1 instead of flex: 1 in scrollView content container style as follows.
<ScrollView contentContainerStyle={{ flexGrow: 1, borderColor: 'green', borderWidth: 5 }}>
<View style={styles.box1} />
<View style={styles.box2} />
<View style={styles.box1} />
</ScrollView>
https://snack.expo.io/HkkEVoh6Z
I believe your problem is that you are telling the ScrollView to occupy all available space with flex=1 but the thing is that ScrollView works differently. It automatically renders all its children so it does work different with flex. That is the difference against a normal ListView or FlatList which have better performance.
I believe this snack solves that issue: https://snack.expo.io/SkxN9GOT-
Basically, I am getting the height of the device and setting the ScrollView with a fixed height, based on (screenHeight - the current height of the red box).
The best thing to do is to wrap your ScrollView in a View and control that view with flex, your scroll view will follow.
This is a little example
<View style={{flex: 1, flexDirection: 'column',}}>
<View style={{flex:5, backgroundColor : 'green' }}>
<ScrollView style={{margin:50, backgroundColor : 'pink' }}>
<Text> Hello Scroll View </Text>
<Text> Hello Scroll View </Text>
<Text> Hello Scroll View </Text>
<Text> Hello Scroll View </Text>
<Text> Hello Scroll View </Text>
<Text> Hello Scroll View </Text>
</ScrollView>
</View>
<View style={{flex:1, backgroundColor : 'blue' }}>
<Text> Hello Static View </Text>
</View>
</View>
This answer has already been provided how to do it.
But here's an explanation why you cannot do by your method. The styles given in contentContainerStyle is
applied to the scroll view content container which wraps all of the child views.
So when you apply flex: 1 to contentContainer it takes full height of ScrollView whose height is also flex: 1 as its parent View.
You can also simulate -
the ability to let the red container down to push up the upper box
by adding a parent to ScrollView and apply style in the parent
<View style={styles.root}>
<View style={{ flex: 1, borderColor: 'green', borderWidth: 5 }}>
<ScrollView>
<View style={styles.box1} />
<View style={styles.box2} />
<View style={styles.box1} />
</ScrollView>
</View>
<View style={{ height: this.state.height, backgroundColor: 'red' }}>
<TouchableOpacity onPress={() => this.setState({ height: this.state.height + 10 })}>
<Text>Click</Text>
</TouchableOpacity>
</View>
</View>
Try this one it will 100% solve your problem
import React, { Component } from 'react';
import { AppRegistry, View,ScrollView } from 'react-native';
export default class AlignItemsBasics extends Component {
render() {
return (
// Try setting `alignItems` to 'flex-start'
// Try setting `justifyContent` to `flex-end`.
// Try setting `flexDirection` to `row`.
<View style={{ flex: 1,flexDirection: 'column' }}>
<View style={{ height: 50, backgroundColor: 'powderblue'}} />
<View style={{ flex: 1, backgroundColor: 'skyblue'}} >
<ScrollView>
<View style={{ flexDirection: 'column' , minHeight: 'fit-content'}} >
<View style={{ height:150, backgroundColor: 'red'}} />
<View style={{ minHeight: 'fit-content', backgroundColor: '#fe3222' }} />
<View style={{ height:150, backgroundColor: '#fff222'}} />
<View style={{ height:150, backgroundColor: '#555222'}} />
</View>
</ScrollView>
</View>
</View>
);
}
};
// skip this line if using Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => AlignItemsBasics);
I'm trying to make a simple view with 2 subviews - v1, v2 aligned horizontally and each taking 50% of the screen width.
To achieve this, I'm using the following code:
<View style={{flexDirection: 'row'}}>
<View style={{flex:1}}>
<View style={{flex:1}}>
</View>
I've also tried playing with other attributes- flexWrap, justifyContent.
However, everytime the views get stacked one after the other and doesn't take 50% of the screen. What am I doing wrong?
EDIT: The actual piece of code I'm using:
<View>
<Text style={styles.place}>New Delhi</Text>
<View style={{flexDirection: 'row'}}>
<DayTimeComponent style={{flex:1}}/>
<DayTimeComponent style={{flex:1}}/>
</View>
</View>
You can achieve this easily using react-native-easy-grid
Code:
import { Col, Row, Grid } from "react-native-easy-grid";
export default class StackOverflow extends Component {
render() {
return (
<View style={{flex:1}}>
<Grid>
<Col style={{backgroundColor:'yellow',alignItems:'center',justifyContent:'center'}}><Text>v1</Text></Col>
<Col style={{backgroundColor:'green',alignItems:'center',justifyContent:'center'}}><Text>v2</Text></Col>
</Grid>
</View>
);
}
}
Result:
You can also create custom layouts, for eg: if you need a 75%-25% split then all you need to do is
<Col size={75}></Col>
<Col size={25}></Col>
Set "flex:1" on both the container views. Like so:
<View style={{flex:1}}>
<Text style={styles.place}>New Delhi</Text>
<View style={{flexDirection: 'row', flex:1}}>
<DayTimeComponent style={{flex:1}}/>
<DayTimeComponent style={{flex:1}}/>
</View>
</View>
In my Andoid app. I have a clickable linear layout that I've generated programmaticly, and I want it to turn green when it is pressed to indicate that it is clickable, like a button would. How would I go about doing this?
This is my code i implemented in my Header layout.
<LinearLayout
android:id="#+id/back_lay"
android:layout_width="46dp"
android:layout_height="46dp"
android:layout_marginLeft="10dp"
android:background="#android:color/transparent"
android:gravity="center_vertical|center_horizontal" >
<Button
android:id="#+id/ib_back_music"
android:layout_width="30dp"
android:layout_height="32dp"
android:layout_marginLeft="5dp"
android:background="#drawable/back_btn_sel"
android:clickable="true"
android:gravity="center_vertical|center_horizontal|center" />
</LinearLayout>
private LinearLayout lLinearLayout;
//OnCreate
lLinearLayout = (LinearLayout) findViewById(R.id.back_lay);
lLinearLayout.setOnClickListener(new
{
#Override
public void onClick(View v)
{
lLinearLayout.setBackgroundColor(Color.BLACK);
}
});
This is the Android equivalent of this iOS question.
Trying to create a view that contains a MapView at about 20% of the screen (under an ActionBar...) and the rest of the screen is a ScrollView that when scrolling down, overlaps on top of the MapView and hides it. In short like FourSquare's Android app.
Any ideas?
I've made an implementation based on AndroidSlidingUpPanel (many thanks to this project).
Details http://android.amberfog.com/?p=915
Source code with example: https://github.com/dlukashev/AndroidSlidingUpPanel-foursquare-map-demo
LAST UPDATE
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<fragment
android:id="#+id/map_fragment"
android:name="com.myapp.MapFragment"
android:layout_width="match_parent"
android:layout_height="fill_parent" />
<fragment
android:id="#id/list_fragment"
android:name="com.myapp.ListFragment"
android:layout_width="wrap_content"
android:layout_height="fill_parent" />
Then I add an invisible header to the list like so:
#Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.listview, container, false);
SwipeListView listView = (SwipeListView) view.findViewById(R.id.venue_list);
// An invisible view added as a header to the list and clicking it leads to the mapfragment
TextView invisibleView = new TextView(inflater.getContext());
invisibleView.setBackgroundColor(Color.TRANSPARENT);
invisibleView.setHeight(300);
invisibleView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
listener.moveToMapFragment();
}
});
listView.addHeaderView(invisibleView);
This is hardly ideal, but it works. I hope it helps someone..
The easiest solution is to add a margin to your slider content (second parameter of the SlidingUpPanel) and then remove the fading background. All done from the XML.
You can just declare in your xml file a ScrollView that embeds a LinearLayout, that embeds a MapView :
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:fillViewport="true" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
...... Your list and other stuff .......
</LinearLayout>
</LinearLayout>
</ScrollView>
Then you can set the size for each element by specifying the layout_weight attribute
EDIT
IvanDanDo, following our discussion I found this link that may do what you want (not sure though, I didn't try it) : Android: Have an arbitrary View slide under another View like the software keyboard does