ollija / react-native-sortable-grid Goto Github PK
View Code? Open in Web Editor NEWDrag-drop-sortable grid view for react native
License: MIT License
Drag-drop-sortable grid view for react native
License: MIT License
Thank you for this react-native-sortable-grid
, its working awesome.
I know its headache but you need to refactor treshold to threshold.
Everything behaves normally when parent is removed
I followed the example provided in the GitHub, I'm using a basic 4x4 grid layout and my code is working perfectly and performance is great on IOS. I have 15 boxes of data. However, when I run it on android, it gives me 30 boxes (it duplicates boxes 1-15 another time for some reason?) and then u can't drag/drop boxes, the entire phone just gets buggy and laggy, and sometimes a box disappears. Is anyone else having these issues?
Is there any example of how to dynamically add and remove children? If you add a child to the array do you have to re-render all of the children, or would it be best to use a state object?
I come across some problem that items mess up when I add new items, I try to add a new item, and delete previous one of the new item, I find that new item was deleted meanwhile. how to do it? would u give me an example for the functionality of addition.
Would be cool to have an easy way to change the deletion view.
e.g. being able to put an "X" in the top corner similar to native iOS
Implemented the grid inside a ScrollView and it works fine, but when I have a ton of icons and I want to drag one of the last ones to the first place or viceversa, I have to stop every time I reach the end of the scrollview, release the icon, scroll, and continue dragging later.
¿Anyone has encountered a way to automatically scroll up or down when dragging so it isn't necessary to stop halfway through? Something like this but with the grid:
Should try to update to use useNativeDriver for smooth 60fps.
how to slide item to left or right and delete
I'm looking into adding an item and then trying to re-order the grid to accommodate the new item.
It currently seems like the last time moves but the other blocks do not re-refresh. Is there a method that I am missing for this?
For example, if all of the default widgets are 1x1, I am interested in having widgets on the same grid that are 1x2, or 2x2. Is there support for this?
What I want to do is to perform some action like opening detail screen when I do a short click. How can I achieve same?
Items in the list can be handled in batches, such as move, delete, etc.
Hi, I'm trying to prevent a parent view from scrolling by using the onDragStart
and onDragReleaseevents; however, if the user long presses on an item and immediately let's go without dragging it anywhere, the
onDragReleaseevent is not fired even though the
onDragStart` event did fire.
This means if we disable scrolling on the start event and expect to enable scroll on the release event but it never happens, scroll is locked and the user may not know how to fix it.
I am trying to add renderHeader prop in component like a ListView and have the posibility of drag items over the header.
I download the component code and in index.js
and in render have added:
style={{flex: 1}}
to SortableGrid props.class SortableGrid extends Component {
render = () =>
<Animated.View
style={ this._getGridStyle() }
onLayout={ this.assessGridSize }
>
{ this.props.renderHeader && this.props.renderHeader() }
{ this.state.gridLayout &&
this.items.map( (item, key) =>
<Block
key = { key }
style = { this._getBlockStyle(key) }
onLayout = { this.saveBlockPositions(key) }
panHandlers = { this._panResponder.panHandlers }
delayLongPress = { this.dragActivationTreshold }
onLongPress = { this.activateDrag(key) }
onPress = { this.handleTap(item.props) }
itemWrapperStyle = { this._getItemWrapperStyle(key) }
deletionView = { this._getDeletionView(key) }
>
{item}
</Block>
)}
</Animated.View>
....
}
With that all works fine. But the problem is when i wrap SortableGrid
in a ScrollView
, because the first render all works fine but after scroll, component re-render and break the ScrollView cutting end elements.
MyScreen code:
return (
<ScrollView scrollEnabled={this.state.scrollEnabled}>
<SortableGrid
style={{flex: 1}}
dragActivationTreshold={50}
onDragStart={ () => this.onDragStart() }
onDragRelease={ () => this.onDragRelease() }
renderHeader={ () => this.renderHeader() }
>
{
_.map(data, (item, index) => {
return this.renderItem(item, index)
})
}
</SortableGrid>
</ScrollView>
)
@ollija can you help me with this? If all works fine i could do PR
If anyone else is using in a ScrollView this might help you. Mainly you have to lock and unlock the scrollview's "scrollEnabled" property.
<ScrollView
ref='myScrollView'
...
Callback
setLockGrid(mode) {
this.refs.myScrollView.setNativeProps({ scrollEnabled: mode });
}
Pass down this callback to your Sortable Grid implementation:
<FavoritesGrid setLock={this.setLockGrid.bind(this)} style={{flex:1}}/>
Then when you setup your Sortable Grid you need to set the callbacks:
<SortableGrid
onDragEnd = { this.onDragEnd.bind(this) }
onDragStart = { this.onDragStart.bind(this) }
...
onDragStart(){
this.props.setLock(false);
}
onDragEnd(){
this.props.setLock(true);
}
RN -> 0.52.0
React -> 16.2.0
I use react-native-navigation, maybe that causes the problem?
Hi @ollija, I tried a long time solving this.
Grid displays fine, but drag and drop fails.
Is this a known Issue? Does anybody have similar problems?
Even the simplest example does not work:
<SortableGrid
blockTransitionDuration = { 400 }
activeBlockCenteringDuration = { 200 }
itemsPerRow = { 4 }
dragActivationTreshold = { 200 }
onDragRelease = { (itemOrder) => console.log("Drag was released, the blocks are in the following order: ", itemOrder) }
onDragStart = { () => console.log("Some block is being dragged now!") }
>
{
this.state.abc.map( (letter, index) =>
<View key={index} style={styles.block}>
<Text style={{color: 'white', fontSize: 50}}>{letter}</Text>
</View>
)
}
</SortableGrid>
@ollija thank you for the amazing work in this library!
I have some specific needs that I would like to discuss and implement, but without a contributing file, I don't know where to start. Could you please make one?
Thanks in advance.
Great plugin, I am working on a feature where you can delete items like you can on iPhone home screen (close item on top left) which I replaced "delete.png" with a vector icon.
However running into some issues with the event getting dispatched multiple times. Was wondering if you had any insight.
<TouchableOpacity
style = {{ flex: 1 }}
delayLongPress = { this.dragActivationTreshold }
onLongPress = { this.activateDrag(key) }
onPress = { this.handleTap(item.props) }>
<View style={ this._getItemWrapperStyle(key) }>
{ item }
</View>
</TouchableOpacity>
{ this.state.deleteModeOn &&
< TouchableWithoutFeedback onPress={this._onDeleteButtonPress(key)} style={{position:'absolute', top:3, left:3, backgroundColor:'transparent'}}>
<Icon
style={[ ,
{color:'#333', backgroundColor:'transparent'}]}
size={22} name={'ios-close-circle'}></Icon>
</TouchableWithoutFeedback>
}
The method
_onDeleteButtonPress = (blockIndex) => {
alert("Deleting "+blockIndex);
//this.setState({activeBlock: blockIndex});
//this.deleteBlock();
}
Instead of the _onDeleteButtonPress method only being called when I touch the X icon, it gets called multiple times (twice) on initial press of the Item itself.
This is what it's required in my current project, when user drags away an item, I'd like to keep that space blank instead of let a nearby item filling the blank. The idea is to make items snapping to the grid but not snapping to each other.
Thoughts and comments are welcome, thanks!
I want to sort items based on priority and priority can be set on Tap or Drag. is this possible?
Any plans to use ListView for long grids?
<SortableGrid
itemsPerRow = { 3 }
dragStartAnimation = {{transform: []}}
>
{
['a', 'b', 'c'].map( (letter, index) =>
<TouchableOpacity key={index}>
<Text>{letter}</Text>
</TouchableOpacity>
)
}
</SortableGrid>
I see the last commit was 9 months ago. I also see that "componentWillReceiveProps" is still being used. So I'm wondering what is the level of support for this? I'd like to add functionality which allows dragging between grids, but not sure if I should.
The library works great on iPhone simulator (it's amazing!), however when testing on an actual iPhone, I can't drag anything.
Do I need to do anything special to get it to work on an actual device?
iPhone 7, iOS 10
"react-native": "^0.36.0",
"react-native-sortable-grid": "^1.2.1",
Hello,
When I update the state inside of my own component, along with onDeleteItem. For instance this works.
onDragStart = () => {
this.setState({toScrollEnabled: false});
}
<SortableGrid
ref={'SortableGrid'}
itemsPerRow={4}
// onDeleteItem={this.onDeleteItem}
onDeleteItem={item => console.log('Item was deleted:', item)}
//onDragStart={this.onDragStart}
onDragRelease={this.onDragRelease}
>
But this doesn't. It adds an extra component to the end of the array?
<SortableGrid
ref={'SortableGrid'}
itemsPerRow={4}
// onDeleteItem={this.onDeleteItem}
onDeleteItem={item => console.log('Item was deleted:', item)}
onDragStart={this.onDragStart}
onDragRelease={this.onDragRelease}
>
I didn't notice this until after I started modifying the source, but is there a reason the package isn't trying to maintain sort order?
As in your examples, when dragging "A" somewhere else in the alphabet, the other letters will rearrange themselves to the nearest space instead of maintaining their ordering.
edit: similar package with this as default behavior https://github.com/react-native-component/react-native-smart-sortable-sudoku-grid
want some inactive items not to be sorted, inactive property is not working as desired.
For inactive child property, document doesn't explains much.
<View key={i}
style={{height:90, width:90, borderRadius:45, borderColor:"#9b9b9b", borderWidth:3, alignItems:"center", justifyContent:"center"}}
inactive ={true}
>
<Entypo name="circle-with-plus" style={{color:"#9b9b9b"}} size={76} />
</View>
my react-native code is
<SortableGrid
key={"sortableGrid"}
style={{ margin: 10,flex:1}}
itemsPerRow={3}
dragActivationTreshold={100}
ref={'SortableGrid'}
dragStartAnimation={this.getDragStartAnimation()}
onDragRelease={(item, index) => this.onDragRelease(item, index)}
onDragStart={() => this.startCustomAnimation()}
>
{
this.state.media.map((item, index) => {
return (
item !== "empty"
?
<View style={{ height: 106, width: 106, alignSelf: "center" }} key={unique-key-${index}
}>
<Image source={{ uri: item.image_id === "" ? item.thumbnail : item.image }} style={{
width: 100,
height: 100,
borderRadius: 20,
alignSelf: "center",
borderColor: '#ababab',
borderWidth: 2
}} />
<TouchableOpacity style={[styles.Indicator, { borderWidth: 1, borderColor: "#ababab", borderRadius: 10, backgroundColor: "#FFF" }]} onPress={() => this.removeMedia({ item, index })}>
<Image source={require("../../assets/images/error.png")} style={{ height: 20, width: 20, alignSelf: "center", }} resizeMode="contain" />
:
<TouchableOpacity onPress={() => this.getImageOrVideo(index)} key={key-${index}
} inactive = {true}>
<View style={[styles.cellEmptyImg, { alignSelf: "center" },]}>
<Image source={require("../../assets/images/button.png")} style={{ height: 50, width: 50, }} resizeMode="cover" />
add photo
)
})
}
Hi, Love you work great stuff but i need your assistance with the dimensions of the widgets as am trying to achieve something like google keep with different dimensions for each widget however when i try to set the height and width for each widget it doesn't seem to have an effect it just displays the default dimensions i guess, Is there a way that i can set the dimensions of the widget?
I'm using the library to create a photo grid that supports adding, deletion, and reordering of photos. I am storing all of my data in a redux store from which the grid is populated. Adding and deleting photos works fine, but I'm having some trouble with rearranging photos.
Here is the data structure I'm using for my photos ( in Redux reducer):
photos: {"0" : null, "1" : null, "2" : null, "3" : null, "4" : null, "5" : null}
This is my component code so far:
` const PhotoUpload = ({ navigation }) => {
// Redux hooks
const photos = useSelector(state => state.user.user.photos);
const dispatch = useDispatch();
// function to reorder the images
reorderImages = (itemOrder) => {
const temp = {}
const photosCopy = {...photos}
const array = itemOrder.itemOrder
for (let index = 0; index < array.length; index++) {
let e = array[index]
let key = e.key
let order = e.order
temp[order] = photosCopy[key]
}
dispatch(setStorePhotos(temp));
}
return (
<>
<SortableGrid
// ... other props ommitted
onDragRelease = { (itemOrder) => reorderImages(itemOrder) }
onDragStart = { (photo) => console.log("Block: ", photo, " is being dragged now!") } >
{
Object.keys(photos).map((key) =>
<View key={ key } onTap={() => this.pickSingle(true, false, key)} >
<Image defaultSource={ require('./default-avatar.png') } source={ getPhoto(key) } />
//... add/delete buttons ommitted
</View>
)
}
</SortableGrid>
</>
)
}`
I am testing adding two images and then swapping their positions. After the reorderImages function returns, I log all of the filenames in the photos object. Everything is in the right order:
0 IMG_0002.JPG
1 IMG_0001.JPG
2 null
3 null
4 null
5 null
The images in the Grid are still in the original order though:
And when I go to delete the first image, it thinks I'm clicking the second image, so it just sets the first image to null and doesn't slide the other image to the left (part of my deletion logic).
I don't know whether I have a logical error or if this is some interaction between redux and the SortableGrid but I've already spent a significant amount of time working on this and I need some fresh eyes.
In Drag-and-drop -style rearrangable grid view,
Drag-and-drop works fine as far as it is assigned with items prior.
But drag and drop doesnot work if i try to add new items to it dynamically.
Please help with a solution.
onLayout={this.saveBlockPositions(key)} leads to this problem,In the process of checking
This :
this.blockWidth = nativeEvent.layout.width / this.itemsPerRow
Should be changed to this :
this.blockWidth = Math.floor(nativeEvent.layout.width / this.itemsPerRow)
`If nativeEvent.layout.width / this.itemsPerRow isn't an integer (or maybe if the decimal part is greater than 0.5?), then it causes last block in the row to be rendered on the next row. I had this problem on android.
Hi @ollija, I have several 'cell's inside this sortable grid. Some cells have props connected to a remote API. Apparently the cells that are inside the sortable_grid don't update and those which are outside do update.
My main question is: Do props inside are updatable?
<SortableGrid>
<View style={styles.defaultCell} key={key_item}>
<Text style={styles.cellTitle}>Availability</Text>
<Text style={styles.cellValue}>{this.props.activity}%</Text>. //This doesn't update
</View>
</SortableGrid>
<View style={styles.defaultCell} key={key_item}>
<Text style={styles.cellTitle}>Availability</Text>
<Text style={styles.cellValue}>{this.props.activity}%</Text>. //This does get updated
</View>
Thank you for the module. It's not an issue but perhaps you can guide me or implement it in future releases. Is there any way of comparing the elements (numbers) and deciding if the re-arranged elements are sorted from the lowest to the highest? How would I approach it?
Thanks
I am using RN 0.52.2
After turn on toggleDeleteMode On, make one or more deletion, and then turn it off.
Drag is no longer work, but the Wiggle still shows.
Its nice to have a method to be called to shuffle the views . I'm using the component to make a puzzle game and such a feature is a bit needed in this context .
Thanks
This grid has performance issue if we have more than 30 blocks, tested on Android Samsung S4 (JS Dev Mode is off).
I have a 3x2 grid set up and it works fine on my ios simulator. However, when I load my app on an android simulator or my phone (galaxy s9+) the drag n drop functionality takes a massive hit making it unusable. When I tap to toggle delete mode it doesn't display the "trash" icons like it does on ios and the drag to delete functionality is compromised. Is there anything I can do to improve performance on android?
I set itemHeight property, but it didn't work,
Running npm install will install this package at 2.0.0. In order to get the latest version with most of the configuration props mentioned in the documentation (2.0.1) you will need to run npm i react-native-sortable-grid@https://github.com/ollija/react-native-sortable-grid --save
.
真机上好卡,是什么原因?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.